diff --git a/ops_boba/api/README.md b/ops_boba/api/README.md index 66d84f34d0..083f125b9b 100644 --- a/ops_boba/api/README.md +++ b/ops_boba/api/README.md @@ -12,12 +12,6 @@ This folder contains all Boba APIs for the production This API is used to swap BOBA for a small amount of ETH paying a zero gas fee -## Service API - -#### - `get.wallet.version` - - This API returns the gateway version - ## Token API #### - `get.supply` @@ -72,4 +66,4 @@ This folder contains all Boba APIs for the production #### - ` get.l2.pendingexits` - This API returns all pending exits \ No newline at end of file + This API returns all pending exits diff --git a/ops_boba/api/service-api/serverless.yml b/ops_boba/api/service-api/serverless.yml deleted file mode 100644 index dbf54de4b5..0000000000 --- a/ops_boba/api/service-api/serverless.yml +++ /dev/null @@ -1,33 +0,0 @@ -service: sls-boba-service # NOTE: update this with your service name - -provider: - name: aws - runtime: python3.7 - stackName: sls-boba-service - stage: prod - region: us-east-1 - role: ${file(env.yml):ROLE} - -package: - exclude: - - .gitignore - individually: true - -functions: - webwallet_version: - handler: webwallet_version.webwallet_version - memorySize: 10240 # optional, in MB, default is 1024 - timeout: 60 # optional, in seconds, default is 6 - vpc: - securityGroupIds: - - sg-0efc38a735756ed2f - subnetIds: - - subnet-838566a2 - - subnet-d92acfbf - events: - - http: - path: get.wallet.version - method: get - cors: true - layers: - - ${file(env.yml):LAYERS} diff --git a/ops_boba/api/service-api/webwallet_version.py b/ops_boba/api/service-api/webwallet_version.py deleted file mode 100644 index bbc8340072..0000000000 --- a/ops_boba/api/service-api/webwallet_version.py +++ /dev/null @@ -1,19 +0,0 @@ -import json - -def webwallet_version(event, context): - - response = { - "statusCode": 201, - "headers": { - "Access-Control-Allow-Origin": "*", - "Access-Control-Allow-Credentials": True, - "Strict-Transport-Security": "max-age=63072000; includeSubdomains; preload", - "X-Content-Type-Options": "nosniff", - "X-Frame-Options": "DENY", - "X-XSS-Protection": "1; mode=block", - "Referrer-Policy": "same-origin", - "Permissions-Policy": "*", - }, - "body": json.dumps({"version": "1.3.3"}) - } - return response diff --git a/packages/boba/gateway/.env.example b/packages/boba/gateway/.env.example index d157b924e9..137a89312a 100644 --- a/packages/boba/gateway/.env.example +++ b/packages/boba/gateway/.env.example @@ -4,7 +4,6 @@ REACT_APP_GAS_POLL_INTERVAL=30000 SKIP_PREFLIGHT_CHECK=true REACT_APP_WALLET_VERSION=1.0.10 REACT_APP_ENV=dev -REACT_APP_CHAIN=mainnet REACT_APP_STATUS=normal REACT_APP_SPEED_CHECK= REACT_APP_GA4_MEASUREMENT_ID= diff --git a/packages/boba/gateway/package.json b/packages/boba/gateway/package.json index 1a56a4cde4..619a2aa982 100644 --- a/packages/boba/gateway/package.json +++ b/packages/boba/gateway/package.json @@ -7,13 +7,13 @@ "buildenv-prod": "NODE_ENV=production react-env --dest build", "get_artifacts": "./scripts/get_all_artifacts.sh", "serve": "npm run buildenv-prod && serve -s build -l 3000 -c public/serve.json", - "start": "npm run buildenv-dev && react-scripts start", - "build:prod": "GENERATE_SOURCEMAP=false REACT_APP_ENV=prod react-scripts build", - "build:dev": "GENERATE_SOURCEMAP=false REACT_APP_ENV=dev react-scripts build", + "start": "npm run buildenv-dev && REACT_APP_WALLET_VERSION=$npm_package_version react-scripts start", + "build:prod": "GENERATE_SOURCEMAP=false REACT_APP_WALLET_VERSION=$npm_package_version REACT_APP_ENV=prod react-scripts build", + "build:dev": "GENERATE_SOURCEMAP=false REACT_APP_WALLET_VERSION=$npm_package_version REACT_APP_ENV=dev react-scripts build", "audit-check": "audit-ci --moderate", "postinstall": "patch-package", - "deploy:mainnet": "GENERATE_SOURCEMAP=false REACT_APP_ENV=prod react-scripts build && aws s3 rm s3://boba-gateway --recursive && aws s3 sync build s3://boba-gateway && aws s3 cp s3://boba-gateway/index.html s3://boba-gateway/index.html --metadata-directive REPLACE --cache-control max-age=0 --content-type text/html", - "deploy:goerli": "GENERATE_SOURCEMAP=false REACT_APP_ENV=prod REACT_APP_CHAIN=goerli react-scripts build && aws s3 rm s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr --recursive && aws s3 sync build s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr && aws s3 cp s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr/index.html s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr/index.html --metadata-directive REPLACE --cache-control max-age=0 --content-type text/html" + "deploy:mainnet": "GENERATE_SOURCEMAP=false REACT_APP_WALLET_VERSION=$npm_package_version REACT_APP_ENV=prod react-scripts build && aws s3 rm s3://boba-gateway --recursive && aws s3 sync build s3://boba-gateway && aws s3 cp s3://boba-gateway/index.html s3://boba-gateway/index.html --metadata-directive REPLACE --cache-control max-age=0 --content-type text/html", + "deploy:goerli": "GENERATE_SOURCEMAP=false REACT_APP_WALLET_VERSION=$npm_package_version REACT_APP_ENV=prod REACT_APP_CHAIN=goerli react-scripts build && aws s3 rm s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr --recursive && aws s3 sync build s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr && aws s3 cp s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr/index.html s3://ethereum-testnet-gateway-gatewaybucket-jn968xk15skr/index.html --metadata-directive REPLACE --cache-control max-age=0 --content-type text/html" }, "dependencies": { "@apollo/client": "^3.5.10", @@ -57,6 +57,7 @@ "react-zendesk": "^0.1.13", "recharts": "^2.1.10", "redux": "^4.1.2", + "redux-persist": "^6.0.0", "redux-thunk": "^2.3.0", "sass": "^1.51.0", "serve": "^11.3.2", diff --git a/packages/boba/gateway/readme.md b/packages/boba/gateway/readme.md index 94217488e0..d0c289feb8 100644 --- a/packages/boba/gateway/readme.md +++ b/packages/boba/gateway/readme.md @@ -10,7 +10,6 @@ gateway.boba.betwork. | SKIP_PREFLIGHT_CHECK | N/A | N/A | N/A | | REACT_APP_WALLET_VERSION | Yes | N/A | This will be useful while prepare the build. | | REACT_APP_ENV | Yes | dev | This will be used in case of sentry configuration. | -| REACT_APP_CHAIN | Yes | mainnet | Chain where we want to connect the app to like goerli, mainnet | | REACT_APP_STATUS | NO | N/A | To notify the status about any maintainance activity going on. | | REACT_APP_SPEED_CHECK | | | | | REACT_APP_GA4_MEASUREMENT_ID | Yes | N/A | Google analytics api key | diff --git a/packages/boba/gateway/src/actions/farmAction.js b/packages/boba/gateway/src/actions/farmAction.js index aa91df06ef..cdafb74e42 100644 --- a/packages/boba/gateway/src/actions/farmAction.js +++ b/packages/boba/gateway/src/actions/farmAction.js @@ -1,6 +1,6 @@ /* Varna - A Privacy-Preserving Marketplace - Varna uses Fully Homomorphic Encryption to make markets fair. + Varna uses Fully Homomorphic Encryption to make markets fair. Copyright (C) 2021 Enya Inc. Palo Alto, CA This program is free software: you can redistribute it and/or modify @@ -48,7 +48,6 @@ const getFarmInfoSuccess = (L1PoolInfo, L1UserInfo, L2PoolInfo, L2UserInfo) => ( // }) export const getFarmInfo = () => async (dispatch) => { - console.log("getFarmInfo()") dispatch(getFarmInfoBegin()) const [L1LPInfo, L2LPInfo] = await Promise.all([ networkService.getL1LPInfo(), @@ -122,4 +121,4 @@ export function fetchL1LPBalance(currency) { export function fetchL2LPBalance(currency) { return createAction('FETCH/L2LPBALANCE', () => networkService.L2LPBalance(currency)) -} \ No newline at end of file +} diff --git a/packages/boba/gateway/src/actions/networkAction.js b/packages/boba/gateway/src/actions/networkAction.js index 95594100e9..150daedadf 100644 --- a/packages/boba/gateway/src/actions/networkAction.js +++ b/packages/boba/gateway/src/actions/networkAction.js @@ -13,7 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import gasService from 'services/gas.service' import networkService from 'services/networkService' +import transctionService from 'services/transaction.service' import { createAction } from './createAction' export function fetchBalances() { @@ -21,17 +23,16 @@ export function fetchBalances() { } export function fetchGas() { - return createAction('GAS/GET', () => networkService.getGas()) + return createAction('GAS/GET', () => gasService.getGas()) } export function addTokenList() { - console.log("addTokenList") return createAction('TOKENLIST/GET', () => networkService.addTokenList()) } export function fetchTransactions() { return createAction('TRANSACTION/GETALL', () => - networkService.getTransactions() + transctionService.getTransactions() ) } @@ -47,10 +48,6 @@ export function fetchFastExits() { ) } -export function fetchExits() { - return createAction('EXIT/GETALL', () => networkService.getExits()) -} - export function exitBOBA(token, value) { return createAction('EXIT/CREATE', () => networkService.exitBOBA(token, value) @@ -243,3 +240,25 @@ export function enableBrowserWallet(network) { export function getAllAddresses() { return createAction('GET/ALL/ADDRESS', () => networkService.getAllAddresses()) } + + +/********************************/ +/******ONE GATEWAY ACTIONS *****/ +/********************************/ +/** + * @params + * network - ethereum, bnb, fantom, avax, moonbase, moonbeam + * networkType - MAINNET, TESTNET +*/ +export function setNetwork(payload) { + return function (dispatch) { + return dispatch({ type: 'NETWORK/SET', payload: payload }) + } +} + +// to update the active network. +export function setActiveNetwork(payload) { + return function (dispatch) { + return dispatch({ type: 'NETWORK/SET/ACTIVE' }) + } +} diff --git a/packages/boba/gateway/src/actions/serviceAction.js b/packages/boba/gateway/src/actions/serviceAction.js deleted file mode 100644 index c4ba7ec60e..0000000000 --- a/packages/boba/gateway/src/actions/serviceAction.js +++ /dev/null @@ -1,18 +0,0 @@ -import walletServiceAxiosInstance from 'api/walletServiceAxios' -import { WALLET_VERSION } from 'util/constant' - -export const checkVersion = () => { - walletServiceAxiosInstance('temporary_placeholder').get('get.wallet.version').then((res) => { - if (res.status === 201) { - if (res.data !== '') { - if (res.data.version !== WALLET_VERSION) { - caches.keys().then(async function (names) { - await Promise.all(names.map((name) => caches.delete(name))) - }) - } - } - } else { - return '' - } - }) -} diff --git a/packages/boba/gateway/src/actions/setupAction.js b/packages/boba/gateway/src/actions/setupAction.js index 4ec75974dc..eebeb9c777 100644 --- a/packages/boba/gateway/src/actions/setupAction.js +++ b/packages/boba/gateway/src/actions/setupAction.js @@ -30,12 +30,6 @@ export function setBaseState(enabled) { } } -export function setNetwork(network) { - return function (dispatch) { - return dispatch({ type: 'SETUP/NETWORK/SET', payload: network }) - } -} - export function setLayer(layer) { return function (dispatch) { return dispatch({ type: 'SETUP/LAYER/SET', payload: layer }) diff --git a/packages/boba/gateway/src/actions/signAction.js b/packages/boba/gateway/src/actions/signAction.js index 7562a3e252..562d869f2d 100644 --- a/packages/boba/gateway/src/actions/signAction.js +++ b/packages/boba/gateway/src/actions/signAction.js @@ -26,7 +26,3 @@ export async function updateSignatureStatus_exitTRAD ( sigStatus ) { export async function updateSignatureStatus_depositLP ( sigStatus ) { store.dispatch({type: 'DEPOSIT/LP/SIGNED',payload: sigStatus}) } - -export async function updateSignatureStatus_depositTRAD ( sigStatus ) { - store.dispatch({type: 'DEPOSIT/TRAD/SIGNED',payload: sigStatus}) -} diff --git a/packages/boba/gateway/src/actions/verifierAction.js b/packages/boba/gateway/src/actions/verifierAction.js index 7cd2e34ffb..8684c26863 100644 --- a/packages/boba/gateway/src/actions/verifierAction.js +++ b/packages/boba/gateway/src/actions/verifierAction.js @@ -13,9 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import networkService from 'services/networkService' +import verifierService from 'services/verifier.service' import { createAction } from './createAction' export function fetchVerifierStatus() { - return createAction('VERIFIER/GET', () => networkService.fetchVerifierStatus()) + return createAction('VERIFIER/GET', () => verifierService.getVerifierStatus()) } diff --git a/packages/boba/gateway/src/api/buyerAxios.js b/packages/boba/gateway/src/api/buyerAxios.js deleted file mode 100644 index df7fb2dc19..0000000000 --- a/packages/boba/gateway/src/api/buyerAxios.js +++ /dev/null @@ -1,19 +0,0 @@ -import axios from 'axios' - -import { getBaseServices } from 'util/masterConfig' - -/* -might need to be updated - not sure this makes sense for local? -*/ - -const _buyerAxiosInstance = axios.create({ - baseURL: getBaseServices().BUYER_OPTIMISM_API_URL, -}) - -_buyerAxiosInstance.interceptors.request.use((config) => { - config.headers['Accept'] = 'application/json' - config.headers['Content-Type'] = 'application/json' - return config -}) - -export default _buyerAxiosInstance diff --git a/packages/boba/gateway/src/api/metaTransactionAxios.js b/packages/boba/gateway/src/api/metaTransactionAxios.js index 8f0bc37044..9d6cfc235d 100644 --- a/packages/boba/gateway/src/api/metaTransactionAxios.js +++ b/packages/boba/gateway/src/api/metaTransactionAxios.js @@ -1,23 +1,11 @@ import axios from 'axios' -import { getBaseServices } from 'util/masterConfig' -export default function metaTransactionAxiosInstance(networkGateway){ +export default function metaTransactionAxiosInstance(networkConfig) { + const url = networkConfig['META_TRANSACTION'] - let axiosInstance = null; - - if(networkGateway === 'local') { - return null //does not make sense on local - } - else if (networkGateway === 'goerli') { - axiosInstance = axios.create({ - baseURL: getBaseServices().GOERLI_META_TRANSACTION, - }) - } - else if (networkGateway === 'mainnet') { - axiosInstance = axios.create({ - baseURL: getBaseServices().MAINNET_META_TRANSACTION, - }) - } + let axiosInstance = axios.create({ + baseURL: url, + }) axiosInstance.interceptors.request.use((config) => { config.headers['Accept'] = 'application/json' diff --git a/packages/boba/gateway/src/api/omgxWatcherAxios.js b/packages/boba/gateway/src/api/omgxWatcherAxios.js index f313540d3e..2255191cf0 100644 --- a/packages/boba/gateway/src/api/omgxWatcherAxios.js +++ b/packages/boba/gateway/src/api/omgxWatcherAxios.js @@ -1,31 +1,15 @@ import axios from 'axios' -import { getNetwork } from 'util/masterConfig' -const nw = getNetwork() -export default function omgxWatcherAxiosInstance(networkGateway){ +export default function omgxWatcherAxiosInstance(networkConfig) { + const watcherUrl = networkConfig[ 'OMGX_WATCHER_URL' ] - let axiosInstance = null - - if(networkGateway === 'local') { - return null //does not make sense on local - } - else if (networkGateway === 'goerli') { - if(nw.goerli.OMGX_WATCHER_URL === null) return - axiosInstance = axios.create({ - baseURL: nw.goerli.OMGX_WATCHER_URL, - }) - } - else if (networkGateway === 'mainnet') { - - if(nw.mainnet.OMGX_WATCHER_URL === null) return - axiosInstance = axios.create({ - baseURL: nw.mainnet.OMGX_WATCHER_URL, - }) - } + let axiosInstance = axios.create({ + baseURL: watcherUrl, + }) axiosInstance.interceptors.request.use((config) => { - config.headers['Accept'] = 'application/json' - config.headers['Content-Type'] = 'application/json' + config.headers[ 'Accept' ] = 'application/json' + config.headers[ 'Content-Type' ] = 'application/json' return config }) diff --git a/packages/boba/gateway/src/api/sellerAxios.js b/packages/boba/gateway/src/api/sellerAxios.js deleted file mode 100644 index 63556b73b0..0000000000 --- a/packages/boba/gateway/src/api/sellerAxios.js +++ /dev/null @@ -1,14 +0,0 @@ -import axios from 'axios' -import { SELLER_OPTIMISM_API_URL } from 'util/constant' - -const _sellerAxiosInstance = axios.create({ - baseURL: SELLER_OPTIMISM_API_URL, -}) - -_sellerAxiosInstance.interceptors.request.use((config) => { - config.headers['Accept'] = 'application/json' - config.headers['Content-Type'] = 'application/json' - return config -}) - -export default _sellerAxiosInstance diff --git a/packages/boba/gateway/src/api/serviceAxios.js b/packages/boba/gateway/src/api/serviceAxios.js deleted file mode 100644 index 2736e8f20c..0000000000 --- a/packages/boba/gateway/src/api/serviceAxios.js +++ /dev/null @@ -1,14 +0,0 @@ -import axios from 'axios' -import { SERVICE_OPTIMISM_API_URL } from 'util/constant' - -const _serviceAxiosInstance = axios.create({ - baseURL: SERVICE_OPTIMISM_API_URL, -}) - -_serviceAxiosInstance.interceptors.request.use((config) => { - config.headers[ 'Accept' ] = 'application/json' - config.headers[ 'Content-Type' ] = 'application/json' - return config -}) - -export default _serviceAxiosInstance diff --git a/packages/boba/gateway/src/api/verifierWatcherAxios.js b/packages/boba/gateway/src/api/verifierWatcherAxios.js index 270aa035b6..f6df944dbe 100644 --- a/packages/boba/gateway/src/api/verifierWatcherAxios.js +++ b/packages/boba/gateway/src/api/verifierWatcherAxios.js @@ -1,31 +1,19 @@ import axios from 'axios' -import { getNetwork } from 'util/masterConfig' -const nw = getNetwork() -export default function verifierWatcherAxiosInstance(networkGateway){ +export default function verifierWatcherAxiosInstance(networkConfig) { + const url = networkConfig[ 'VERIFIER_WATCHER_URL' ] - let axiosInstance = null - - if(networkGateway === 'local') { - return null //does not make sense on local - } - else if (networkGateway === 'goerli') { - if(nw.goerli.VERIFIER_WATCHER_URL === null) return - axiosInstance = axios.create({ - baseURL: nw.goerli.VERIFIER_WATCHER_URL, - }) + if (!url) { + return null; } - else if (networkGateway === 'mainnet') { - if(nw.mainnet.VERIFIER_WATCHER_URL === null) return - axiosInstance = axios.create({ - baseURL: nw.mainnet.VERIFIER_WATCHER_URL, - }) - } + let axiosInstance = axios.create({ + baseURL: url + }) axiosInstance.interceptors.request.use((config) => { - config.headers['Accept'] = 'application/json' - config.headers['Content-Type'] = 'application/json' + config.headers[ 'Accept' ] = 'application/json' + config.headers[ 'Content-Type' ] = 'application/json' return config }) diff --git a/packages/boba/gateway/src/api/walletServiceAxios.js b/packages/boba/gateway/src/api/walletServiceAxios.js deleted file mode 100644 index 48245ba8cd..0000000000 --- a/packages/boba/gateway/src/api/walletServiceAxios.js +++ /dev/null @@ -1,17 +0,0 @@ -import axios from 'axios' -import { getBaseServices } from 'util/masterConfig' - -export default function walletServiceAxiosInstance(networkGateway){ - - let axiosInstance = axios.create({ - baseURL: getBaseServices().WALLET_SERVICE, - }) - - axiosInstance.interceptors.request.use((config) => { - config.headers['Accept'] = 'application/json' - config.headers['Content-Type'] = 'application/json' - return config - }) - - return axiosInstance -} diff --git a/packages/boba/gateway/src/components/SentryWrapper/SentryWrapper.js b/packages/boba/gateway/src/components/SentryWrapper/SentryWrapper.js index 56b6b8485d..c1f480c6a0 100644 --- a/packages/boba/gateway/src/components/SentryWrapper/SentryWrapper.js +++ b/packages/boba/gateway/src/components/SentryWrapper/SentryWrapper.js @@ -1,14 +1,14 @@ import React, { useEffect } from 'react' import * as Sentry from '@sentry/react'; -import { BrowserTracing } from '@sentry/tracing'; import { Typography } from '@mui/material'; -import { APP_CHAIN, APP_ENV, SENTRY_DSN } from 'util/constant'; +import { APP_ENV, SENTRY_DSN } from 'util/constant'; +import { useSelector } from 'react-redux'; +import { selectActiveNetwork } from 'selectors/networkSelector'; /** * It's function which wraps compnent and add sentry integration on top of it. * - * * @param {*} children * @returns wrapp component */ @@ -17,6 +17,8 @@ const SentryWrapper = ({ children }) => { + const network = useSelector(selectActiveNetwork()); + useEffect(() => { const dns = SENTRY_DSN; // if no sentry dsn pass don't even initialize. @@ -24,13 +26,13 @@ const SentryWrapper = ({ // Sentry initializations. Sentry.init({ dsn: SENTRY_DSN, - environment: `${APP_ENV}-${APP_CHAIN}`, + environment: `${APP_ENV}-${network}`, integrations: [ new Sentry.Integrations.GlobalHandlers({ onunhandledrejection: false, /// will avoid to send unhandle browser error. onerror: false, }), - new BrowserTracing() + // new BrowserTracing() ], ignoreErrors: [ 'top.GLOBALS', //stop sentry to report the random plugin / extensions errors. @@ -46,7 +48,7 @@ const SentryWrapper = ({ ], tracesSampleRate: 1.0, initialScope: { - tags: { 'network': APP_CHAIN } + tags: { network } }, beforeSend: (event, hint) => { // Avoid sending the sentry events on local env. @@ -67,7 +69,7 @@ const SentryWrapper = ({ return () => { Sentry.close(2000) // to close the sentry client connection on unmounting. }; - }, []); + }, [network]); return <> diff --git a/packages/boba/gateway/src/components/button/Button.js b/packages/boba/gateway/src/components/button/Button.js index 0bcdb99f6c..d8dcd6bb0c 100644 --- a/packages/boba/gateway/src/components/button/Button.js +++ b/packages/boba/gateway/src/components/button/Button.js @@ -14,10 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ import React from 'react' -import { CircularProgress, Tooltip } from '@mui/material' +import { CircularProgress } from '@mui/material' import { Button as ButtonMUI } from '@mui/material' +import Tooltip from '../tooltip/Tooltip' -function Button ({ +function Button({ children, style, onClick, @@ -31,14 +32,12 @@ function Button ({ tooltip = '', size, className, - triggerTime, + triggerTime }) { - - if(disabled || loading) - pulsate = false + if (disabled || loading) pulsate = false let timeDefined = false - if(typeof triggerTime !== 'undefined') { + if (typeof triggerTime !== 'undefined') { timeDefined = true } @@ -47,13 +46,17 @@ function Button ({ React.useEffect(() => { if (loading) { - const timer = setInterval(()=>{setTime(new Date())}, 1000) - return () => {clearInterval(timer)} + const timer = setInterval(() => { + setTime(new Date()) + }, 1000) + return () => { + clearInterval(timer) + } } }, [loading]) - let waitTime = (now-triggerTime) / 1000 - if(waitTime < 0) waitTime = 0 + let waitTime = (now - triggerTime) / 1000 + if (waitTime < 0) waitTime = 0 waitTime = Math.round(waitTime) const muiProps = { @@ -77,19 +80,17 @@ function Button ({ {children} - {(disabled || loading) && timeDefined && (waitTime > 3) && -
- {waitTime}s ago -
- } - {loading && + {(disabled || loading) && timeDefined && waitTime > 3 && ( +
{waitTime}s ago
+ )} + {loading && (
- +
- } + )}
- + ) } diff --git a/packages/boba/gateway/src/components/faucet/Faucet.js b/packages/boba/gateway/src/components/faucet/Faucet.js new file mode 100644 index 0000000000..2d8f7d724c --- /dev/null +++ b/packages/boba/gateway/src/components/faucet/Faucet.js @@ -0,0 +1,149 @@ +import React, { useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { selectActiveNetworkType } from 'selectors/networkSelector'; + +import * as G from 'containers/Global.styles' +import { Box, Typography, Input } from '@mui/material'; + +import faucetService from 'services/faucet.service'; +import { openAlert } from 'actions/uiAction'; +import { selectLayer, selectWalletAddress } from 'selectors/setupSelector'; +import { NETWORK_TYPE } from 'util/network/network.util'; +import Copy from 'components/copy/Copy'; +import Button from 'components/button/Button'; +import twitter from 'images/twitter.png' +import { Md5 } from 'ts-md5'; +import networkService from 'services/networkService'; + + +/** + * @Faucet + * - only accessible on L2 for testnet env. + */ + +const Faucet = (props) => { + + const dispatch = useDispatch(); + const activeNetworkType = useSelector(selectActiveNetworkType()); + const layer = useSelector(selectLayer()) + const walletAddress = useSelector(selectWalletAddress()) + + + const [ tweetUrl, setTweetUrl ] = useState("") + const [ isClaimFaucetLoading, setIsClaimFaucetLoading ] = useState(false) + const [ faucetErrorMsg, setFaucetErrorMsg ] = useState("") + + let bobaTag = '' + if (walletAddress) + bobaTag = Md5.hashStr(walletAddress.toLowerCase().substring(2)) + + let BT = '' + let tweet = '' + if (bobaTag) { + BT = "BOBA" + bobaTag.substring(0, 9).toUpperCase() + tweet = networkService.networkConfig.twitterFaucetPromotionText + BT + } + + async function claimAuthenticatedFaucetTokens() { + try { + setIsClaimFaucetLoading(true) + const tweetId = tweetUrl?.match(/twitter\.com\/.*\/status\/(\d+)/)[ 1 ] + const res = await faucetService.getTestnetETHAuthenticatedMetaTransaction(tweetId) + if (!res) { + dispatch(openAlert('Faucet request submitted')) + } else { + setFaucetErrorMsg(res) + } + } catch (err) { + let error = err.message.match(/execution reverted: (.*)\\+"}}/) + if (error) { + error = error[ 1 ] + } else { + error = err?.message ?? err + } + setFaucetErrorMsg(error) + } finally { + setIsClaimFaucetLoading(false) + } + } + + if (layer === 'L2' && + activeNetworkType === NETWORK_TYPE.TESTNET) + { + return ( + + + + + Developer Twitter/Turing test token fountain - your Boba Bubble:{" "} + {BT} + + + + + Welcome developers. + For testnet BOBA and ETH, tweet your Boba Bubble and + then paste the tweet link in the field below. + + + Tweet Now + + + + For the Tweet link, tap the share icon, tap "Share Tweet via", and finally select "Copy link to Tweet". + + + setTweetUrl(e?.target?.value.split('?')[ 0 ])} //remove the superfluous stuff after the "?" + /> + + + You are limited to one fountain call per twitter account per day. + The transaction will not show in your history since it's a MetaTransaction (the gas is covered by Boba). + + + + + {faucetErrorMsg ? {faucetErrorMsg} : null} + + + ) + } + + return null; +} + +export default Faucet; diff --git a/packages/boba/gateway/src/components/icons/AlertIcon.js b/packages/boba/gateway/src/components/icons/AlertIcon.js index 4848245a5e..55aa4da590 100644 --- a/packages/boba/gateway/src/components/icons/AlertIcon.js +++ b/packages/boba/gateway/src/components/icons/AlertIcon.js @@ -3,8 +3,7 @@ import { useTheme } from "@mui/material/styles"; function AlertIcon() { const theme = useTheme(); - const isLight = theme.palette.mode === 'light'; - const color = theme.palette.common[isLight ? 'black' : 'white']; + const color = theme.palette.primary.alert; return ( - - + + ) } diff --git a/packages/boba/gateway/src/components/icons/DiscordIcon.js b/packages/boba/gateway/src/components/icons/DiscordIcon.js index fed5892541..02bd257475 100644 --- a/packages/boba/gateway/src/components/icons/DiscordIcon.js +++ b/packages/boba/gateway/src/components/icons/DiscordIcon.js @@ -1,17 +1,26 @@ -import { useTheme } from "@mui/material"; -import * as React from "react"; +import { useTheme } from '@mui/material' +import * as React from 'react' -function DiscordIcon() { - - const theme = useTheme(); - const isLight = theme.palette.mode === 'light'; - const color = theme.palette.common[isLight ? 'black' : 'white']; +function DiscordIcon(props) { + const theme = useTheme() + const isLight = theme.palette.mode === 'light' + const color = theme.palette.common[isLight ? 'black' : 'white'] return ( - - + + - ); + ) } -export default DiscordIcon; +export default DiscordIcon diff --git a/packages/boba/gateway/src/components/icons/L2ToL1Icon.js b/packages/boba/gateway/src/components/icons/L2ToL1Icon.js index fd399d9bb5..6a833eacb0 100644 --- a/packages/boba/gateway/src/components/icons/L2ToL1Icon.js +++ b/packages/boba/gateway/src/components/icons/L2ToL1Icon.js @@ -45,4 +45,4 @@ export const L2ToL1Icon = ({ color }) => { ) } -export default L2ToL1Icon \ No newline at end of file +export default L2ToL1Icon diff --git a/packages/boba/gateway/src/components/icons/WalletIcon.js b/packages/boba/gateway/src/components/icons/WalletIcon.js index 325c9ef757..f79ca79df1 100644 --- a/packages/boba/gateway/src/components/icons/WalletIcon.js +++ b/packages/boba/gateway/src/components/icons/WalletIcon.js @@ -2,11 +2,11 @@ import * as React from "react" import { useTheme } from "@mui/material/styles"; function WalletIcon() { - + const theme = useTheme(); const isLight = theme.palette.mode === 'light'; const color = theme.palette.common[ isLight ? 'black' : 'white' ]; - + return ( + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + ) +} + +export default AvalancheIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L1/BNBIcon.js b/packages/boba/gateway/src/components/icons/chain/L1/BNBIcon.js new file mode 100644 index 0000000000..1a50af5d04 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L1/BNBIcon.js @@ -0,0 +1,38 @@ +import * as React from "react" + +function BnbIcon({ selected = false }) { + + + if (!selected) { + return + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + ) +} + +export default BnbIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L1/EthereumIcon.js b/packages/boba/gateway/src/components/icons/chain/L1/EthereumIcon.js new file mode 100644 index 0000000000..c5358e7d56 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L1/EthereumIcon.js @@ -0,0 +1,36 @@ +import * as React from "react" + +function EthereumIcon({ selected = false }) { + + + if (!selected) { + return + + + + + + + + + + + + + } + + return + + + + + + + + + + + +} + +export default EthereumIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L1/FantomIcon.js b/packages/boba/gateway/src/components/icons/chain/L1/FantomIcon.js new file mode 100644 index 0000000000..c7d9bcc6a1 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L1/FantomIcon.js @@ -0,0 +1,24 @@ +import * as React from "react" + +function EthereumIcon({ selected = false }) { + + + if (!selected) { + return + + + + + } + + return ( + + + + + + + ) +} + +export default EthereumIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L1/MoonbaseIcon.js b/packages/boba/gateway/src/components/icons/chain/L1/MoonbaseIcon.js new file mode 100644 index 0000000000..468746fa0f --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L1/MoonbaseIcon.js @@ -0,0 +1,55 @@ +import * as React from "react" + +function MoonbaseIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + ) +} + +export default MoonbaseIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L1/MoonbeamIcon.js b/packages/boba/gateway/src/components/icons/chain/L1/MoonbeamIcon.js new file mode 100644 index 0000000000..b2be77d929 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L1/MoonbeamIcon.js @@ -0,0 +1,36 @@ +import * as React from "react" + +function MoonbeamIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + ) +} + +export default MoonbeamIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js new file mode 100644 index 0000000000..cc9492dc0d --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobaAvaxIcon.js @@ -0,0 +1,59 @@ +import * as React from "react" + +function BobaAvaxIcon({ selected = false }) { + + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default BobaAvaxIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobaBNBIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobaBNBIcon.js new file mode 100644 index 0000000000..ce5bccfea6 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobaBNBIcon.js @@ -0,0 +1,56 @@ +import * as React from "react" + +function BobaBnbIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default BobaBnbIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobaFantomIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobaFantomIcon.js new file mode 100644 index 0000000000..1ce663a5f7 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobaFantomIcon.js @@ -0,0 +1,50 @@ +import * as React from "react" + + +function EthereumIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + ) +} + +export default EthereumIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobaIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobaIcon.js new file mode 100644 index 0000000000..359b5741cf --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobaIcon.js @@ -0,0 +1,59 @@ +import * as React from "react" + +function EthereumIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + + + + } + + return + + + + + + + + + + + + + + + + + + + + + + + +} + +export default EthereumIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobabaseIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobabaseIcon.js new file mode 100644 index 0000000000..846fd908b7 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobabaseIcon.js @@ -0,0 +1,80 @@ +import * as React from "react" + +function BobabaseIcon({ selected = false }) { + + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default BobabaseIcon diff --git a/packages/boba/gateway/src/components/icons/chain/L2/BobabeamIcon.js b/packages/boba/gateway/src/components/icons/chain/L2/BobabeamIcon.js new file mode 100644 index 0000000000..47976fcfe5 --- /dev/null +++ b/packages/boba/gateway/src/components/icons/chain/L2/BobabeamIcon.js @@ -0,0 +1,55 @@ +import * as React from "react" + +function EthereumIcon({ selected = false }) { + + if (!selected) { + return + + + + + + + + + + + + + + + + + + + + + + } + + return ( + + + + + + + + + + + + + + + + + + + + + + ) +} + +export default EthereumIcon diff --git a/packages/boba/gateway/src/components/listFarm/listFarm.js b/packages/boba/gateway/src/components/listFarm/listFarm.js index 2c21227a2d..a920c744ac 100644 --- a/packages/boba/gateway/src/components/listFarm/listFarm.js +++ b/packages/boba/gateway/src/components/listFarm/listFarm.js @@ -208,7 +208,7 @@ class ListFarm extends React.Component { } return ( - + {pageLoading ? ( @@ -476,10 +476,10 @@ class ListFarm extends React.Component { Staked {logAmount(userInfo.amount, decimals, 2)} - diff --git a/packages/boba/gateway/src/components/listToken/listToken.js b/packages/boba/gateway/src/components/listToken/listToken.js index 7691e7b4fc..5c3e52c73f 100644 --- a/packages/boba/gateway/src/components/listToken/listToken.js +++ b/packages/boba/gateway/src/components/listToken/listToken.js @@ -20,72 +20,73 @@ import { getCoinImage } from 'util/coinImage' import * as S from './listToken.styles' import { BRIDGE_TYPE } from 'util/constant' -function ListToken({ - token, - chain, - networkLayer, - disabled, - loading -}) { - const [ dropDownBox, setDropDownBox ] = useState(false) +function ListToken({ token, chain, networkLayer, disabled, loading }) { + const [dropDownBox, setDropDownBox] = useState(false) const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('md')) - const dispatch = useDispatch(); - const enabled = (networkLayer === chain) ? true : false + const dispatch = useDispatch() + const enabled = networkLayer === chain ? true : false const logo = getCoinImage(token.symbol) const lookupPrice = useSelector(selectLookupPrice) - const amountInNumber = token.symbol === 'ETH' ? - Number(logAmount(token.balance, token.decimals, 3)): - Number(logAmount(token.balance, token.decimals, 2)) + const amountInNumber = + token.symbol === 'ETH' + ? Number(logAmount(token.balance, token.decimals, 3)) + : Number(logAmount(token.balance, token.decimals, 2)) - const amount = token.symbol === 'ETH' ? - Number(logAmount(token.balance, token.decimals, 3)).toLocaleString(undefined, { minimumFractionDigits: 3, maximumFractionDigits: 3 }) : - Number(logAmount(token.balance, token.decimals, 2)).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + const amount = + token.symbol === 'ETH' + ? Number(logAmount(token.balance, token.decimals, 3)).toLocaleString( + undefined, + { minimumFractionDigits: 3, maximumFractionDigits: 3 } + ) + : Number(logAmount(token.balance, token.decimals, 2)).toLocaleString( + undefined, + { minimumFractionDigits: 2, maximumFractionDigits: 2 } + ) const handleModalClick = (modalName, token, fast) => { dispatch(openModal(modalName, token, fast)) } - async function doSettle_v0 () { + async function doSettle_v0() { await dispatch(settle_v0()) } - async function doSettle_v1 () { + async function doSettle_v1() { await dispatch(settle_v1()) } - async function doSettle_v2 () { + async function doSettle_v2() { await dispatch(settle_v2()) } - async function doSettle_v2OLO () { + async function doSettle_v2OLO() { await dispatch(settle_v2OLO()) } - async function doSettle_v3 () { + async function doSettle_v3() { await dispatch(settle_v3()) } - async function doSettle_v3OLO () { + async function doSettle_v3OLO() { await dispatch(settle_v3OLO()) } - if (isMobile) { return ( - + logo {token.symbol} - + - + { - setDropDownBox(!dropDownBox); + setDropDownBox(!dropDownBox) }} - isMobile={isMobile}> + isMobile={isMobile} + > - - + + @@ -122,45 +130,63 @@ function ListToken({ {isMobile && dropDownBox ? ( - - {enabled && chain === 'L1' && + {enabled && chain === 'L1' && ( <> - {token.symbol === 'BOBA' && - - } - - } + {token.symbol === 'BOBA' && ( + + )} + + )} - {enabled && chain === 'L2' && + {enabled && + chain === 'L2' && token.symbol !== 'OLO' && token.symbol !== 'xBOBA' && token.symbol !== 'WAGMIv0' && @@ -168,42 +194,50 @@ function ListToken({ token.symbol !== 'WAGMIv2' && token.symbol !== 'WAGMIv2-Oolong' && token.symbol !== 'WAGMIv3' && - token.symbol !== 'WAGMIv3-Oolong' && - <> - + token.symbol !== 'WAGMIv3-Oolong' && ( + <> + - + - - - } + + + )} - {enabled && chain === 'L2' && token.symbol === 'OLO' && + {enabled && chain === 'L2' && token.symbol === 'OLO' && ( <> - } + )} - {enabled && chain === 'L2' && token.symbol === 'WAGMIv0' && -
+ {enabled && chain === 'L2' && token.symbol === 'WAGMIv0' && ( +
- } + )} - {enabled && chain === 'L2' && token.symbol === 'WAGMIv1' && -
+ {enabled && chain === 'L2' && token.symbol === 'WAGMIv1' && ( +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv2' && -
+ )} + {enabled && chain === 'L2' && token.symbol === 'WAGMIv2' && ( +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv2-Oolong' && -
- -
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv3' && -
+ +
+ )} + {enabled && chain === 'L2' && token.symbol === 'WAGMIv3' && ( +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv3-Oolong' && -
- -
- } + +
+ )} ) : null} @@ -353,13 +417,13 @@ function ListToken({ return ( - + logo {token.symbol} - + - + - {enabled && chain === 'L1' && + {enabled && chain === 'L1' && ( <> - {token.symbol === 'BOBA' && - - - } + {token.symbol === 'BOBA' && ( + + )} - } - {enabled && chain === 'L2' && + )} + {enabled && + chain === 'L2' && token.symbol !== 'OLO' && token.symbol !== 'xBOBA' && token.symbol !== 'WAGMIv0' && @@ -429,40 +511,48 @@ function ListToken({ token.symbol !== 'WAGMIv2' && token.symbol !== 'WAGMIv2-Oolong' && token.symbol !== 'WAGMIv3' && - token.symbol !== 'WAGMIv3-Oolong' && - <> - - - - - } - {enabled && chain === 'L2' && token.symbol === 'OLO' && + token.symbol !== 'WAGMIv3-Oolong' && ( + <> + + + + + )} + {enabled && chain === 'L2' && token.symbol === 'OLO' && ( <> - } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv0' && -
-
+ }} + > +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv1' && -
-
+ }} + > +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv2' && -
-
+ }} + > +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv2-Oolong' && -
-
+ }} + > +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv3' && -
-
+ }} + > +
- } - {enabled && chain === 'L2' && token.symbol === 'WAGMIv3-Oolong' && -
-
+ }} + > +
- } + )} diff --git a/packages/boba/gateway/src/components/listToken/listToken.styles.js b/packages/boba/gateway/src/components/listToken/listToken.styles.js index b1278b89d5..3ad3b9e279 100644 --- a/packages/boba/gateway/src/components/listToken/listToken.styles.js +++ b/packages/boba/gateway/src/components/listToken/listToken.styles.js @@ -7,7 +7,7 @@ export const Content = styled(Box)(({ theme }) => ({ gap: '20px', width: '100%', padding: '10px', - borderBottom: theme.palette.primary.borderBottom + borderBottom: theme.palette.primary.borderBottom, })) export const TableBody = styled(Box)(({ theme }) => ({ @@ -15,9 +15,9 @@ export const TableBody = styled(Box)(({ theme }) => ({ alignItems: 'center', justifyContent: 'space-between', textAlign: 'center', - [ theme.breakpoints.down('sm') ]: { - gap: '10px' - } + [theme.breakpoints.down('sm')]: { + gap: '10px', + }, })) export const TableCell = styled(Box)(({ theme, isMobile }) => ({ @@ -25,16 +25,16 @@ export const TableCell = styled(Box)(({ theme, isMobile }) => ({ alignItems: 'center', justifyContent: 'center', width: '20%', - [ theme.breakpoints.down('sm') ]: { + [theme.breakpoints.down('sm')]: { minWidth: '20%', - width: isMobile ? '10%' : 'unset' - } -})); + width: isMobile ? '10%' : 'unset', + }, +})) export const TextTableCell = styled(Typography)` - opacity: ${(props) => !props.enabled ? "0.4" : "1.0"}; + opacity: ${(props) => (!props.enabled ? '0.4' : '1.0')}; font-weight: 700; -`; +` export const DropdownWrapper = styled(Box)(({ theme }) => ({ display: 'flex', @@ -42,7 +42,7 @@ export const DropdownWrapper = styled(Box)(({ theme }) => ({ alignItems: 'center', flexDirection: 'row', gap: '10px', - [ theme.breakpoints.down('sm') ]: { - gap: '5px' - } + [theme.breakpoints.down('sm')]: { + gap: '5px', + }, })) diff --git a/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.js b/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.js index 7bb2d4b7c9..ee99f218fa 100644 --- a/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.js +++ b/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.js @@ -1,4 +1,3 @@ - /* Copyright 2021-present Boba Network. @@ -17,6 +16,7 @@ limitations under the License. */ import React, { useCallback } from 'react' import { useDispatch, useSelector } from 'react-redux' import { openError, openAlert } from 'actions/uiAction' +import { HelpOutline } from '@mui/icons-material' import { selectAccountEnabled, @@ -36,96 +36,117 @@ import { isEqual } from 'lodash' import BN from 'bignumber.js' import { logAmount } from 'util/amountConvert.js' -import { HelpOutline } from '@mui/icons-material' +import networkService from 'services/networkService.js' +import { + selectActiveNetworkName, +} from 'selectors/networkSelector.js' -function FeeSwitcher() { +function FeeSwitcher() { const dispatch = useDispatch() const accountEnabled = useSelector(selectAccountEnabled()) const feeUseBoba = useSelector(selectBobaFeeChoice()) + const networkName = useSelector(selectActiveNetworkName()) + const layer = useSelector(selectLayer()) const l2Balances = useSelector(selectlayer2Balance, isEqual) - const l2BalanceETH = l2Balances.filter((i) => i.symbol === 'ETH') - const balanceETH = l2BalanceETH[0] - + const l2BalanceNativeToken = l2Balances.filter((i) => i.symbol === networkService.L1NativeTokenSymbol) + const balanceETH = l2BalanceNativeToken[ 0 ] const l2BalanceBOBA = l2Balances.filter((i) => i.symbol === 'BOBA') const balanceBOBA = l2BalanceBOBA[0] - const dispatchSwitchFee = useCallback(async (targetFee) => { - - //console.log("balanceBOBA:",balanceBOBA) - //console.log("balanceETH:",balanceETH) - - let tooSmallETH = false - let tooSmallBOBA = false - - if(typeof(balanceBOBA) === 'undefined') { - tooSmallBOBA = true - } else { - //check actual balance - tooSmallBOBA = new BN(logAmount(balanceBOBA.balance, 18)).lt(new BN(3.0)) - } - - if(typeof(balanceETH) === 'undefined') { - tooSmallETH = true - } else { - //check actual balance - tooSmallETH = new BN(logAmount(balanceETH.balance, 18)).lt(new BN(0.002)) - } - - if (!balanceBOBA && !balanceETH) { - dispatch(openError('Wallet empty - please bridge in ETH or BOBA from L1')) - return - } - - let res - - if (feeUseBoba && targetFee === 'BOBA') { - // do nothing - already set to BOBA - } - else if ( !feeUseBoba && targetFee === 'ETH' ) { - // do nothing - already set to ETH - } - else if ( !feeUseBoba && targetFee === 'BOBA' ) { - // change to BOBA - if( tooSmallBOBA ) { - dispatch(openError(`You cannot change the fee token to BOBA since your BOBA balance is below 3 BOBA. - If you change fee token now, you might get stuck. Please swap some ETH for BOBA first.`)) + const dispatchSwitchFee = useCallback( + async (targetFee) => { + let tooSmallL1NativeToken = false + // mini balance required for token to use as bridge fee + let minL1NativeBalance = await networkService.estimateMinL1NativeTokenForFee() //0.002 + let tooSmallBOBA = false + + if (typeof balanceBOBA === 'undefined') { + tooSmallBOBA = true } else { - res = await dispatch(switchFee(targetFee)) + //check actual balance + tooSmallBOBA = new BN(logAmount(balanceBOBA.balance, 18)).lt(new BN(1)) } - } - else if (feeUseBoba && targetFee === 'ETH') { - // change to ETH - if( tooSmallETH ) { - dispatch(openError(`You cannot change the fee token to ETH since your ETH balance is below 0.002 ETH. - If you change fee token now, you might get stuck. Please swap some BOBA for ETH first.`)) + + if (typeof balanceETH === 'undefined') { + tooSmallL1NativeToken = true } else { - res = await dispatch(switchFee(targetFee)) + //check actual balance + tooSmallL1NativeToken = new BN(logAmount(balanceETH.balance, 18)).lt( + new BN(minL1NativeBalance) + ) } - } - if (res) { - dispatch(openAlert(`Successfully changed fee to ${targetFee}`)) - } + if (!balanceBOBA && !balanceETH) { + dispatch( + openError('Wallet empty - please bridge in ETH or BOBA from L1') + ) + return + } - }, [ dispatch, feeUseBoba, balanceETH, balanceBOBA ]) + let res + + if (feeUseBoba && targetFee === 'BOBA') { + // do nothing - already set to BOBA + } else if ( + !feeUseBoba && + targetFee === networkService.L1NativeTokenSymbol + ) { + // do nothing - already set to ETH + } else if (!feeUseBoba && targetFee === 'BOBA') { + // change to BOBA + if (tooSmallBOBA) { + dispatch( + openError(`You cannot change the fee token to BOBA since your BOBA balance is below 1 BOBA. + If you change fee token now, you might get stuck. Please swap some ETH for BOBA first.`) + ) + } else { + res = await dispatch(switchFee(targetFee)) + } + } else if ( + feeUseBoba && + targetFee === networkService.L1NativeTokenSymbol + ) { + // change to L1Native Token + if (tooSmallL1NativeToken) { + dispatch( + openError(`You cannot change the fee token to ${networkService.L1NativeTokenSymbol} since your ${networkService.L1NativeTokenSymbol} balance is below ${minL1NativeBalance}. + If you change fee token now, you might get stuck. Please obtain some ${networkService.L1NativeTokenSymbol} first.`) + ) + } else { + res = await dispatch(switchFee(targetFee)) + } + } + + if (res) { + dispatch(openAlert(`Successfully changed fee to ${targetFee}`)) + } + }, + [dispatch, feeUseBoba, balanceETH, balanceBOBA] + ) if (!accountEnabled && layer !== 'L2') { - return - - - - Fee - + return ( + + + + + Fee + + ) } return ( - + Fee @@ -133,21 +154,20 @@ function FeeSwitcher() { onSelect={(e, d) => { dispatchSwitchFee(e.target.value) }} - value={!feeUseBoba ? "ETH" : 'BOBA'} - options={[ { - value: 'ETH', - title: 'ETH', - }, - { - value: 'BOBA', - title: 'BOBA', - description: 'Save another 25% by using Boba as your gas fee token' - } + value={!feeUseBoba ? networkService.L1NativeTokenSymbol : 'BOBA'} + options={[ + { + value: 'BOBA', + title: 'BOBA', + }, + { + value: networkService.L1NativeTokenSymbol, + title: networkService.L1NativeTokenName, + }, ]} /> ) - } export default FeeSwitcher diff --git a/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.styles.js b/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.styles.js index b6143ba7bc..f4b10f49d4 100644 --- a/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/feeSwitcher/FeeSwitcher.styles.js @@ -7,13 +7,13 @@ export const FeeSwitcherWrapper = styled(Box)(({ theme }) => ({ alignItems: 'center', my: 1, gap: '5px', - [ theme.breakpoints.down('md') ]: { - marginTop: '30px' - } + + [theme.breakpoints.down('md')]: { + marginTop: '30px', + }, })) export const FeeSwitcherLabel = styled(Typography)(({ theme }) => ({ whiteSpace: 'nowrap', - textDecoration: 'underline', - opacity: 0.65 + opacity: 0.65, })) diff --git a/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.js b/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.js index 81fea89790..58854b0d61 100644 --- a/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.js +++ b/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.js @@ -7,6 +7,10 @@ import * as S from './GasSwitcher.styles.js' import { selectGas } from 'selectors/balanceSelector' import { selectVerifierStatus } from 'selectors/verifierSelector' import { selectBaseEnabled } from 'selectors/setupSelector.js' +import { + selectActiveNetwork, + selectActiveNetworkName +} from 'selectors/networkSelector.js' import { fetchGas } from 'actions/networkAction.js' import { fetchVerifierStatus } from 'actions/verifierAction.js' @@ -16,6 +20,7 @@ import networkService from 'services/networkService.js' import useInterval from 'hooks/useInterval.js' import { GAS_POLL_INTERVAL } from 'util/constant.js' +import { NETWORK, NETWORK_TYPE } from 'util/network/network.util.js' function GasSwitcher() { const dispatch = useDispatch() @@ -23,9 +28,18 @@ function GasSwitcher() { const baseEnabled = useSelector(selectBaseEnabled()) const gas = useSelector(selectGas) const verifierStatus = useSelector(selectVerifierStatus) - + const networkName = useSelector(selectActiveNetworkName()) + const activeNetwork = useSelector(selectActiveNetwork()) const [ savings, setSavings ] = useState(0) + // fetch the gas on changing deployment + useEffect(() => { + if (baseEnabled) { + dispatch(fetchGas()) + dispatch(fetchVerifierStatus()) + } + }, [ networkName, baseEnabled , dispatch]) + useInterval(() => { if (baseEnabled) { dispatch(fetchGas()) @@ -35,7 +49,7 @@ function GasSwitcher() { useEffect(() => { async function getGasSavings() { - if (networkService.networkGateway === 'mainnet') { + if (networkService.networkType === NETWORK_TYPE.MAINNET) { const l1SecurityFee = await networkService.estimateL1SecurityFee() const l2Fee = await networkService.estimateL2Fee() // The l1 security fee is moved to the l2 fee @@ -47,24 +61,30 @@ function GasSwitcher() { } return 1 } - getGasSavings() - }, [ gas ]) + // fetch savings only if network is ethereum and mainnet. + if (activeNetwork === NETWORK.ETHEREUM) { + getGasSavings() + } + }, [ gas, activeNetwork ]) return ( - Ethereum + {networkName[ 'l1' ]} {gas.gasL1} Gwei - Boba + {networkName[ 'l2' ]} {gas.gasL2} Gwei - - Savings - {savings.toFixed(0)}x - + { + activeNetwork === NETWORK.ETHEREUM && + ( + Savings + {savings.toFixed(0)}x + ) + } L1 {gas.blockL1} diff --git a/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.styles.js b/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.styles.js index cca697a401..aa7d678eae 100644 --- a/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/gasSwitcher/GasSwitcher.styles.js @@ -4,9 +4,6 @@ import { Typography, Box } from '@mui/material' export const Label = styled(Typography)(({ theme }) => ({ opacity: '0.85', fontSize: '0.8em', - [ theme.breakpoints.down('md') ]: { - marginLeft: theme.spacing(1), - } })); export const Value = styled(Typography)(({ theme }) => ({ @@ -20,13 +17,12 @@ export const Menu = styled(Box)(({ theme }) => ({ justifyContent: 'flex-start', alignItems: 'center', gap: '10px', - //background: 'green', 'a': { cursor: 'pointer', }, [ theme.breakpoints.down('md') ]: { width: '100%', - flexDirection: 'column' + flexDirection: 'column', } })) @@ -42,4 +38,4 @@ export const MenuItem = styled(Box)(({ theme }) => ({ width: '100%', justifyContent: 'flex-start', } -})) \ No newline at end of file +})) diff --git a/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.js b/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.js index de392de9b4..d404aaba0c 100644 --- a/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.js +++ b/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.js @@ -14,50 +14,61 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import { Typography, useMediaQuery, ToggleButtonGroup, ToggleButton, IconButton } from '@mui/material' +import { + Typography, + useMediaQuery, + ToggleButtonGroup, + ToggleButton, + IconButton, +} from '@mui/material' import { useTheme } from '@mui/styles' -import { setConnect, setLayer } from 'actions/setupAction.js' +import { setConnect, setConnectBOBA, setConnectETH, setLayer } from 'actions/setupAction.js' import BobaIcon from 'components/icons/BobaIcon.js' import EthereumIcon from 'components/icons/EthereumIcon.js' import React, { useCallback, useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' import { + selectBaseEnabled, selectAccountEnabled, - selectNetwork, selectLayer, selectConnectETH, selectConnectBOBA, - selectConnect + selectConnect, } from 'selectors/setupSelector' +import { + selectActiveNetwork, + selectActiveNetworkIcon, + selectActiveNetworkType, +} from 'selectors/networkSelector' import * as S from './LayerSwitcher.styles.js' import networkService from 'services/networkService' import truncate from 'truncate-middle' -import { - setEnableAccount, - setWalletAddress, -} from 'actions/setupAction' +import { setEnableAccount, setWalletAddress } from 'actions/setupAction' -import { - fetchTransactions, - fetchBalances -} from 'actions/networkAction' +import { fetchTransactions, fetchBalances } from 'actions/networkAction' import { openModal } from 'actions/uiAction' import Button from 'components/button/Button.js' +import { L1_ICONS, L2_ICONS } from 'util/network/network.util.js' +import { LAYER } from 'util/constant.js' -function LayerSwitcher({ - visisble = true -}) { - +function LayerSwitcher({ visisble = true }) { const dispatch = useDispatch() const accountEnabled = useSelector(selectAccountEnabled()) + const baseEnabled = useSelector(selectBaseEnabled()) let layer = useSelector(selectLayer()) - const network = useSelector(selectNetwork()) + const network = useSelector(selectActiveNetwork()) + const networkType = useSelector(selectActiveNetworkType()) + + const networkIcon = useSelector(selectActiveNetworkIcon()) + + const L1Icon = L1_ICONS[networkIcon] + const L2Icon = L2_ICONS[networkIcon] const connectETHRequest = useSelector(selectConnectETH()) const connectBOBARequest = useSelector(selectConnectBOBA()) @@ -66,85 +77,73 @@ function LayerSwitcher({ const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('md')) - const wAddress = networkService.account ? truncate(networkService.account, 6, 4, '...') : '' + const wAddress = networkService.account + ? truncate(networkService.account, 6, 4, '...') + : '' - const chainChangedFromMM = JSON.parse(localStorage.getItem('chainChangedFromMM')) + const chainChangedFromMM = JSON.parse( + localStorage.getItem('chainChangedFromMM') + ) const wantChain = JSON.parse(localStorage.getItem('wantChain')) const chainChangedInit = JSON.parse(localStorage.getItem('chainChangedInit')) const dispatchBootAccount = useCallback(() => { - if (!accountEnabled) initializeAccount() + if (!accountEnabled && baseEnabled) initializeAccount() async function initializeAccount() { - const initialized = await networkService.initializeAccount(network) - - console.log("initialized:",initialized) - - if (initialized === 'wrongnetwork') { + const initialized = await networkService.initializeAccount({ + networkGateway: network, + networkType, + }) + if (initialized === 'nometamask') { + dispatch(openModal('noMetaMaskModal')); + return false; + } else if (initialized === 'wrongnetwork') { dispatch(openModal('wrongNetworkModal')) return false } else if (initialized === false) { - console.log("WP: Account NOT enabled for", network, accountEnabled) dispatch(setEnableAccount(false)) return false } - else if (initialized === 'L1' || initialized === 'L2') { - console.log("WP: Account IS enabled for", initialized) + else if (initialized === LAYER.L1 || initialized === LAYER.L2) { dispatch(setLayer(initialized)) dispatch(setEnableAccount(true)) dispatch(setWalletAddress(networkService.account)) dispatch(fetchTransactions()) dispatch(fetchBalances()) return true - } - else { + } else { return false } } - - }, [ dispatch, accountEnabled, network ]) - - // this will switch chain, if needed, and then connect to Boba - const connectToBOBA = useCallback(() => { - localStorage.setItem('wantChain', JSON.stringify('L2')) - networkService.switchChain('L2') - dispatchBootAccount() - }, [dispatchBootAccount]) - - // this will switch chain, if needed, and then connect to Ethereum - const connectToETH = useCallback(() => { - localStorage.setItem('wantChain', JSON.stringify('L1')) - networkService.switchChain('L1') - dispatchBootAccount() - }, [dispatchBootAccount]) - - const dispatchSwitchLayer = useCallback((targetLayer) => { - - if (targetLayer === 'L1') { - connectToETH() - } - else if (targetLayer === 'L2') { - connectToBOBA() - } else { - // handles the strange targetLayer === null when people click on ETH icon a second time - connectToETH() + }, [dispatch, accountEnabled, network, networkType, baseEnabled]) + + const doConnectToLayer = useCallback((layer) => { + async function doConnect() { + try { + localStorage.setItem('wantChain', JSON.stringify(layer)) + await networkService.switchChain(layer) + dispatchBootAccount() + } catch (err) { + console.log('ERROR', err) + dispatch(setConnectETH(false)); + dispatch(setConnectBOBA(false)); + } } - - }, [ connectToBOBA, connectToETH ]) + doConnect(); + }, [dispatch, dispatchBootAccount]) useEffect(() => { // detect mismatch and correct the mismatch if (wantChain === 'L1' && layer === 'L2') { dispatchBootAccount() - } - else if (wantChain === 'L2' && layer === 'L1') - { + } else if (wantChain === 'L2' && layer === 'L1') { dispatchBootAccount() } - }, [ wantChain, layer, dispatchBootAccount ]) + }, [wantChain, layer, dispatchBootAccount]) useEffect(() => { // auto reconnect to MM if we just switched chains from @@ -153,7 +152,7 @@ function LayerSwitcher({ dispatchBootAccount() localStorage.setItem('chainChangedInit', false) } - }, [ chainChangedInit, dispatchBootAccount ]) + }, [chainChangedInit, dispatchBootAccount]) useEffect(() => { // auto reconnect to MM if we just switched chains from @@ -162,77 +161,88 @@ function LayerSwitcher({ dispatchBootAccount() localStorage.setItem('chainChangedFromMM', false) } - }, [ chainChangedFromMM, dispatchBootAccount ]) + }, [chainChangedFromMM, dispatchBootAccount]) + // listening for l1 connection request useEffect(() => { - if(connectETHRequest) { - localStorage.setItem('wantChain', JSON.stringify('L1')) - networkService.switchChain('L1') - dispatchBootAccount() + if (connectETHRequest) { + doConnectToLayer('L1') } - }, [ connectETHRequest, dispatchBootAccount ]) + }, [ connectETHRequest, doConnectToLayer ]) + // listening for l2 connection request useEffect(() => { if (connectBOBARequest) { - localStorage.setItem('wantChain', JSON.stringify('L2')) - networkService.switchChain('L2') - dispatchBootAccount() + doConnectToLayer('L2') } - }, [ connectBOBARequest, dispatchBootAccount ]) + }, [ connectBOBARequest, doConnectToLayer ]) useEffect(() => { - if(connectRequest) { + if (connectRequest) { dispatchBootAccount() } - }, [ connectRequest, dispatchBootAccount ]) + }, [connectRequest, dispatchBootAccount]) if (!visisble) { return null } - const MobileLayer = ({layer, title, icon, onConnect, isConnected}) => { - return - - {icon} - - - {title} - {(layer === 'L1' || layer === 'L2')? wAddress : 'Not Connected' } - - {!layer ? - : !isConnected ? - : null} - + const MobileLayer = ({ layer, title, icon, onConnect, isConnected }) => { + return ( + + + {icon} + + + + {title}{' '} + + + {layer === LAYER.L1 || layer === LAYER.L2 + ? wAddress + : 'Not Connected'} + + + {!layer ? ( + + ) : !isConnected ? ( + + ) : null} + + ) } if (isMobile) { return ( - } - onConnect={() => connectToETH()} - isConnected={layer === 'L1'} + } + onConnect={() => doConnectToLayer(LAYER.L1)} + isConnected={layer === LAYER.L1} /> - } - onConnect={() => connectToBOBA()} - isConnected={layer === 'L2'} + } + onConnect={() => doConnectToLayer(LAYER.L1)} + isConnected={layer === LAYER.L2} /> ) @@ -243,32 +253,76 @@ function LayerSwitcher({ dispatchSwitchLayer(n)} + onChange={(e, n) => doConnectToLayer(n)} aria-label="text alignment" > - - + + - - + + - {layer === 'L1' ? - Ethereum - {wAddress} - : null} - {!layer ? - Not connected - Select chain to connect - : null} - {layer === 'L2' ? - Boba - {wAddress} - : null} - ) + {layer === 'L1' ? ( + + + Ethereum + + + {wAddress} + + + ) : null} + {!layer ? ( + + + Connect + + + connect wallet + + + ) : null} + {layer === 'L2' ? ( + + + Boba + + + {wAddress} + + + ) : null} + + ) } export default LayerSwitcher diff --git a/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.styles.js b/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.styles.js index 865ebc79ba..cb1e3926a1 100644 --- a/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/layerSwitcher/LayerSwitcher.styles.js @@ -7,7 +7,9 @@ export const LayerSwitcherWrapper = styled(Box)(({ theme }) => ({ alignItems: 'center', background: theme.palette.background.secondary, borderRadius: '12px', - padding: '0' + padding: '0', + cursor: 'pointer', + })); export const LayerContent = styled(Box)(({ theme }) => ({ diff --git a/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.js b/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.js index fbaaa017b8..ab840cf258 100644 --- a/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.js +++ b/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.js @@ -1,56 +1,64 @@ import React, { useState, useEffect } from 'react' import { useSelector } from 'react-redux' -import { useTheme } from '@mui/material' - +import { intersection } from 'lodash' import { selectMonster } from 'selectors/setupSelector' -import { menuItems } from './menuList' +import { MENU_LIST } from './menu.config' +import { useLocation } from 'react-router-dom' import * as S from './MenuItems.styles' -import { DISABLE_VE_DAO } from 'util/constant' +import { PAGES_BY_NETWORK } from 'util/constant' +import { selectActiveNetwork } from 'selectors/networkSelector' +import { useTheme, useMediaQuery } from '@mui/material' + +const MenuItems = ({ + setOpen +}) => { -const MenuItems = () => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('md')); + const menuList = MENU_LIST; - const theme = useTheme() const monsterNumber = useSelector(selectMonster()) - const monstersAdded = menuItems.some(item => item.key === 'Monster') - const [ menuList, setMenuList ] = useState([]); + const network = useSelector(selectActiveNetwork()) - useEffect(() => { - setMenuList(menuItems) - },[]) + const [list, setList] = useState([]) + const location = useLocation() useEffect(() => { - if (monsterNumber > 0 && !monstersAdded) { - setMenuList([ - ...menuItems, + let _menuList = menuList + + if (monsterNumber > 0) { + _menuList = [ + ...menuList, { key: 'Monster', - icon: "MonsterIcon", - title: "MonsterVerse", - url: "/monster" - } - ]) + icon: 'MonsterIcon', + title: 'MonsterVerse', + url: '/monster', + }, + ] } - }, [ monsterNumber, monstersAdded ]); + + let fMenu = _menuList + .filter( + (m) => + intersection([m.key], PAGES_BY_NETWORK[network.toLowerCase()]).length + ) + .filter((m) => !m.disable) + + setList(fMenu) + }, [network, menuList, monsterNumber]) return ( - {menuList.map((item) => { - if (!!Number(DISABLE_VE_DAO) && (['Lock','Vote&Dao'].includes(item.key))) { - return null; - } + {list.map((item) => { return ( - { - return { - color: isActive ? theme.palette.secondary.main : 'inherit' - } - }} - key={item.key} - to={item.url} - > + isMobile ? setOpen(false): null}> + {item.url.split('/')[1] === location.pathname.split('/')[1] && ( + + )} {item.title} - + ) })} diff --git a/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.styles.js b/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.styles.js index 1fdab97e36..9808f45cd1 100644 --- a/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/menuItems/MenuItems.styles.js @@ -1,5 +1,6 @@ import { styled } from '@mui/material/styles' import { NavLink } from 'react-router-dom' +import { ReactComponent as BobaIcon } from '../../../images/boba2/boba2Icon.svg' export const Nav = styled('nav')(({ theme }) => ({ width: '100%', @@ -8,33 +9,45 @@ export const Nav = styled('nav')(({ theme }) => ({ flexDirection: 'row', justifyContent: 'center', alignItems: 'center', - gap: '10px', + gap: '24px', flexWrap: 'wrap', [theme.breakpoints.down('md')]: { width: '100%', - gap: '20px', + gap: '10px', height: '250px', marginTop: '20px', flexWrap: 'nowrap', alignItems: 'flex-start', backgroundColor: theme.palette.background.default, flexDirection: 'column', - } + }, })) -export const MenuItem = styled(NavLink)(({ selected, theme }) => ({ - fontSize: '0.8em', +export const MenuListItem = styled(NavLink)(({ theme }) => ({ + fontSize: '0.9em', fontWeight: 'normal', cursor: 'pointer', height: '22px', textDecoration: 'none', - [ theme.breakpoints.down('md') ]: { + [theme.breakpoints.down('md')]: { fontSize: '20px', fontWeight: '400', - marginLeft: '20px' + marginLeft: '20px', + padding: '0 24px', }, + color: 'inherit', '&:hover': { color: `${theme.palette.secondary.main}`, }, + '&.active': { + color: `${theme.palette.secondary.main}`, + }, +})) +export const MenuIcon = styled(BobaIcon)(({ theme }) => ({ + // display: 'none', + margin: '0 4px -2px 4px', + '&.active': { + display: 'inline', + }, })) diff --git a/packages/boba/gateway/src/components/mainMenu/menuItems/menuList.js b/packages/boba/gateway/src/components/mainMenu/menuItems/menu.config.js similarity index 83% rename from packages/boba/gateway/src/components/mainMenu/menuItems/menuList.js rename to packages/boba/gateway/src/components/mainMenu/menuItems/menu.config.js index 5c65a0142e..3bed2788a9 100644 --- a/packages/boba/gateway/src/components/mainMenu/menuItems/menuList.js +++ b/packages/boba/gateway/src/components/mainMenu/menuItems/menu.config.js @@ -1,6 +1,6 @@ -import { ROUTES_PATH } from "util/constant"; +import { DISABLE_VE_DAO, ROUTES_PATH } from "util/constant"; -export const menuItems = [ +export const MENU_LIST = [ { key: 'Bridge', icon: "WalletIcon", @@ -42,12 +42,14 @@ export const menuItems = [ icon: "LockIcon", title: "Lock", url: ROUTES_PATH.LOCK, + disable: !!Number(DISABLE_VE_DAO) }, { key: 'Vote&Dao', icon: "VoteIcon", title: "Vote&Dao", - url: ROUTES_PATH.VOTE_DAO + url: ROUTES_PATH.VOTE_DAO, + disable: !!Number(DISABLE_VE_DAO) }, { key: 'DAO', diff --git a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.js b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.js new file mode 100644 index 0000000000..1d81221cbd --- /dev/null +++ b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.js @@ -0,0 +1,38 @@ +import React from 'react'; +import { Box, Typography } from '@mui/material'; + +import CheckIcon from '@mui/icons-material/Check' +import { L1_ICONS, L2_ICONS } from 'util/network/network.util'; + +import * as S from './NetworkListItem.styles' + +function NetworkListItem({ + chain, + icon, + label, + name, + onChainChange, + isActive +}) { + + const L1Icon = L1_ICONS[ icon ]; + const L2Icon = L2_ICONS[ icon ]; + + return { + onChainChange({chain, icon, name}) + }}> + + + + + + {label} + {isActive ? : null} + + +} + +export default NetworkListItem; diff --git a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.styles.js b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.styles.js new file mode 100644 index 0000000000..7f559675f6 --- /dev/null +++ b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkListItem.styles.js @@ -0,0 +1,15 @@ +import styled from '@emotion/styled'; +import { MenuItem } from '@mui/material'; + + +export const ChainSwitcherItem = styled(MenuItem)(({ theme }) => ({ + display: 'flex', + cursor: 'pointer', + '&:hover': { + p: { + color: '#BAE21A' + } + } +})); + + diff --git a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.js b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.js index 004aaf0d7c..6355a90dd9 100644 --- a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.js +++ b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.js @@ -1,41 +1,105 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' +import { useDispatch } from 'react-redux'; +import { useSelector } from 'react-redux'; -import { useSelector } from 'react-redux' -import * as S from './NetworkSwitcher.styles.js' +import { Box, Menu, MenuItem, Typography } from '@mui/material'; +import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDown'; -import { selectNetwork } from 'selectors/setupSelector' -import { Box, Typography } from '@mui/material' +import LayerSwitcher from 'components/mainMenu/layerSwitcher/LayerSwitcher'; +import Tabs from 'components/tabs/Tabs'; +import NetworkListItem from './NetworkListItem' -import NetworkIcon from 'components/icons/NetworkIcon' +import {NetworkList, NETWORK_TYPE } from 'util/network/network.util'; + +import * as S from './NetworkSwitcher.styles' +import { setNetwork } from 'actions/networkAction'; +import { selectNetwork, selectNetworkType } from 'selectors/networkSelector'; function NetworkSwitcher() { + const dispatch = useDispatch(); + + const [ anchorEl, setAnchorEl ] = useState(null); + const open = Boolean(anchorEl); + + const [ activeTab, setActiveTab ] = useState(NETWORK_TYPE.MAINNET); + + const network = useSelector(selectNetwork()); + const networkType = useSelector(selectNetworkType()); + + const handleClick = (event) => { + setAnchorEl(event.currentTarget); + }; + + const handleClose = () => { + setAnchorEl(null); + }; + + const onChainChange = ({ icon, chain,name }) => { + dispatch(setNetwork({ + network: chain, + name: name, + networkIcon: icon, + networkType: activeTab, + })); + } - const masterConfig = useSelector(selectNetwork()) + useEffect(() => { + setActiveTab(networkType) + return () => { + setActiveTab(NETWORK_TYPE.MAINNET) + }; + }, [networkType]); return ( - - - - - - Network - + + + + + + + + Please select one to enter the
+ independent chain bridge. +
+
+ + setActiveTab(tab)} + activeTab={activeTab} + tabs={[ NETWORK_TYPE.MAINNET, NETWORK_TYPE.TESTNET ]} + /> + + {NetworkList[ activeTab ].map((chainItem) => { + const isActive = networkType === activeTab && chainItem.chain === network + return { + onChainChange(d); + handleClose(); }} - > - - {masterConfig} - - - - - - + {...chainItem} + /> + })} +
+ ) -}; +} export default NetworkSwitcher; diff --git a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.styles.js b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.styles.js index e9562f3237..28dc0884f3 100644 --- a/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/networkSwitcher/NetworkSwitcher.styles.js @@ -1,90 +1,13 @@ import styled from '@emotion/styled'; -import { Typography } from '@mui/material'; +import { Box } from '@mui/material'; -export const NetworkSwitcherContainer = styled.div` - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-start; - margin-left: -5px; - @include mobile { - font-size: 0.9em; - padding: 10px; - } -`; +export const LayerSwitcherContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + background: theme.palette.background.secondary, + borderRadius: '12px', + padding: '0', + cursor: 'pointer', -export const Label = styled(Typography)(({ theme }) => ({ - marginLeft: theme.spacing(1), - color: theme.palette.text.disabled, })); - -export const NetworkSwitcherWrapper = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: flex-start; - width: 100%; - @include mobile { - flex-direction: column; - } - img { - height: 20px; - } -`; - -export const Menu = styled.div` - display: flex; - flex-direction: row; - align-items: center; - z-index: 1000; - position: relative; - @include mobile { - width: 100%; - justify-content: space-between; - } - a { - cursor: pointer; - } -`; - -export const Chevron = styled.img` - transform: ${props => props.open ? 'rotate(-90deg)' : 'rotate(90deg)'}; - transition: all 200ms ease-in-out; - height: 20px; - margin-bottom: 0; -`; - -export const Dropdown = styled.div` - display: flex; - flex-direction: column; - position: absolute; - left: 0; - top: 27px; - background: #09162B; - border-radius: 12px; - padding: 15px; - box-shadow: -13px 15px 39px rgba(0, 0, 0, 0.16), inset 53px 36px 120px rgba(255, 255, 255, 0.06); - @include mobile { - right: unset; - left: 10px; - width: 150px; - } - a { - background-color: gray; - transition: all 200ms ease-in-out; - padding: 10px 15px; - &:hover { - background-color: gray; - } - } - > p { - cursor: pointer; - } -`; - -export const NetWorkStyle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - cursor: ${(props) => props.walletEnabled !== false ? 'inherit' : 'pointer'}; -`; diff --git a/packages/boba/gateway/src/components/mainMenu/themeSwitcher/ThemeSwitcher.styles.js b/packages/boba/gateway/src/components/mainMenu/themeSwitcher/ThemeSwitcher.styles.js index fe29660700..1233b32947 100644 --- a/packages/boba/gateway/src/components/mainMenu/themeSwitcher/ThemeSwitcher.styles.js +++ b/packages/boba/gateway/src/components/mainMenu/themeSwitcher/ThemeSwitcher.styles.js @@ -7,7 +7,7 @@ export const ThemeSwitcherTag = styled(Box)(({ theme }) => ({ [ theme.breakpoints.down('md') ]: { width: '100%', marginTop: '20px', - marginLeft: '10px' + padding: '0px 20px' } })); diff --git a/packages/boba/gateway/src/components/modal/Modal.js b/packages/boba/gateway/src/components/modal/Modal.js index 4a7073fdee..b842fcbea8 100644 --- a/packages/boba/gateway/src/components/modal/Modal.js +++ b/packages/boba/gateway/src/components/modal/Modal.js @@ -52,8 +52,9 @@ function _Modal({ open={open} onClose={onClose} ismobile={isMobile ? 1 : 0} - // closeAfterTransition - BackdropComponent={S.Backdrop} + slots={{ + backdrop:S.Backdrop + }} disableAutoFocus={true} > @@ -61,7 +62,7 @@ function _Modal({ { !!newStyle ? - + diff --git a/packages/boba/gateway/src/components/modal/Modal.styles.js b/packages/boba/gateway/src/components/modal/Modal.styles.js index 8b08150e6a..90107ac8a0 100644 --- a/packages/boba/gateway/src/components/modal/Modal.styles.js +++ b/packages/boba/gateway/src/components/modal/Modal.styles.js @@ -27,9 +27,11 @@ export const Backdrop = styled('div')` opacity: 0.8; backdrop-filter: blur(10px); -webkit-tap-highlight-color: transparent; -`; +`; -export const Style = styled(Box)` +export const Style = styled(Box, { + shouldForwardProp: (props) => props !== 'transparent' && props !== 'isMobile', +})` display: flex; flex-direction: column; justify-content: space-between; @@ -61,7 +63,7 @@ export const WrapperActionsModal = styled(Box)` margin-top: 50px; `; - + export const ModalHead = styled(Box)(({ theme }) => ({ display: "flex", justifyContent: "space-between", diff --git a/packages/boba/gateway/src/components/pageFooter/PageFooter.js b/packages/boba/gateway/src/components/pageFooter/PageFooter.js index be30fe76fc..31f8782237 100644 --- a/packages/boba/gateway/src/components/pageFooter/PageFooter.js +++ b/packages/boba/gateway/src/components/pageFooter/PageFooter.js @@ -1,4 +1,3 @@ -import { IconButton } from '@mui/material' import { Telegram, Twitter } from '@mui/icons-material' import DiscordIcon from 'components/icons/DiscordIcon' import React from 'react' @@ -6,106 +5,156 @@ import BobaLogo from '../../images/boba2/logo-boba2.svg' import GasSwitcher from '../mainMenu/gasSwitcher/GasSwitcher' import * as S from './PageFooter.styles' import { useMediaQuery, useTheme } from '@mui/material' -import { ROUTES_PATH } from 'util/constant' - -const PageFooter = ({maintenance}) => { +import { LAYER, ROUTES_PATH } from 'util/constant' +import { useSelector } from 'react-redux' +import { selectLayer } from 'selectors/setupSelector' +import { + selectActiveNetwork, + selectActiveNetworkType, +} from 'selectors/networkSelector' +import { getBlockExplorerUrl } from 'util/network/network.util' +const PageFooter = ({ maintenance }) => { const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('md')) + const [isDiscordHover, setIsDiscordHover] = React.useState(false) + + const layer = useSelector(selectLayer()) + const network = useSelector(selectActiveNetwork()) + const networkType = useSelector(selectActiveNetworkType()) - if(maintenance) { + if (maintenance) { return ( + + + + boba logo + + + + + + + Boba Docs + + + + + + + + setIsDiscordHover(true)} + onMouseLeave={() => setIsDiscordHover(false)} + > + + + + + + + Boba Website + + + + + ) + } + return ( - - - boba logo - - - - - Boba Docs - - - - - - - - - - - - + + + Boba Website + aria-label="discord" + onMouseEnter={() => setIsDiscordHover(true)} + onMouseLeave={() => setIsDiscordHover(false)} + > + + + + + + {!isMobile && } - - ) - } - return ( - + - {!isMobile && } - - FAQs - Dev Tools - BobaScope - Blockexplorer - Boba Docs - + + FAQs + + Dev Tools + + BobaScope + + Blockexplorer + + + Boba Docs + + - - - - - - - - - - - Boba Website - - + + Boba Website + ) diff --git a/packages/boba/gateway/src/components/pageFooter/PageFooter.styles.js b/packages/boba/gateway/src/components/pageFooter/PageFooter.styles.js index fa010b278c..92814d94e6 100644 --- a/packages/boba/gateway/src/components/pageFooter/PageFooter.styles.js +++ b/packages/boba/gateway/src/components/pageFooter/PageFooter.styles.js @@ -1,9 +1,10 @@ import { styled } from '@mui/material/styles' import { Box, Divider } from '@mui/material' -import { NavLink } from 'react-router-dom'; +import { NavLink } from 'react-router-dom' +import { IconButton } from '@mui/material' export const Wrapper = styled(Box)(({ theme }) => ({ - display: "flex", + display: 'flex', flexDirection: 'column', justifyContent: 'flex-start', alignItems: 'center', @@ -12,15 +13,13 @@ export const Wrapper = styled(Box)(({ theme }) => ({ //bottom: 0, //width: '100%', //height: '184px', - background: theme.background, - [ theme.breakpoints.down('md') ]: { - marginTop: 0, - height: '450px', + background: theme.palette.background.footer, + [theme.breakpoints.down('md')]: { + marginTop: '10px', + maxHeight: '400px', justifyContent: 'flex-start', padding: '0 20px', }, - [ theme.breakpoints.up('md') ]: { - }, })) export const ContentWrapper = styled(Box)(({ theme }) => ({ @@ -28,20 +27,20 @@ export const ContentWrapper = styled(Box)(({ theme }) => ({ justifyContent: 'space-between', width: '70%', margin: '30px 0', - [ theme.breakpoints.between('sm', 'md') ]: { + [theme.breakpoints.between('sm', 'md')]: { width: '90%', margin: '20px 0', flexDirection: 'column', justifyContent: 'center', - gap: '20px' + gap: '20px', }, - [ theme.breakpoints.down('md') ]: { + [theme.breakpoints.down('md')]: { margin: '20px 0', width: '100%', flexDirection: 'column', justifyContent: 'center', - gap: '20px' - } + gap: '20px', + }, })) export const FooterLink = styled(NavLink)(({ theme }) => ({ @@ -52,9 +51,9 @@ export const FooterLink = styled(NavLink)(({ theme }) => ({ cursor: 'pointer', color: 'unset', '&:hover': { - color: theme.palette.secondary.main, + color: theme.palette.primary.main, }, -})); +})) export const FooterLinkExt = styled(Box)(({ theme }) => ({ //marginLeft: theme.spacing(1), @@ -66,35 +65,46 @@ export const FooterLinkExt = styled(Box)(({ theme }) => ({ '&:hover': { color: theme.palette.secondary.main, }, -})); +})) export const FooterLogoWrapper = styled(Box)(({ theme }) => ({ display: 'flex', alignSelf: 'flex-start', - justifyContent: "center", - alignItems: 'center' + justifyContent: 'center', + alignItems: 'center', })) export const FooterDivider = styled(Divider)(({ theme }) => ({ - background: `${ theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.04)' : 'rgba(3, 19, 19, 0.04)'}`, + background: `${ + theme.palette.mode === 'dark' + ? 'rgba(255, 255, 255, 0.04)' + : 'rgba(3, 19, 19, 0.04)' + }`, boxSizing: 'border-box', - boxShadow: `${ theme.palette.mode === 'dark' ? '0px 4px 4px rgba(0, 0, 0, 0.25)' : 'none'}`, - width: '100%' + boxShadow: `${ + theme.palette.mode === 'dark' ? '0px 4px 4px rgba(0, 0, 0, 0.25)' : 'none' + }`, + width: '100%', })) export const FooterDividerMobile = styled(Divider)(({ theme }) => ({ display: 'none', - [ theme.breakpoints.down('md') ]: { + [theme.breakpoints.down('md')]: { display: 'block', - background: `${ theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, 0.04)' : 'rgba(3, 19, 19, 0.04)'}`, + background: `${ + theme.palette.mode === 'dark' + ? 'rgba(255, 255, 255, 0.04)' + : 'rgba(3, 19, 19, 0.04)' + }`, boxSizing: 'border-box', - boxShadow: `${ theme.palette.mode === 'dark' ? '0px 4px 4px rgba(0, 0, 0, 0.25)' : 'none'}`, - width: '100%' - } + boxShadow: `${ + theme.palette.mode === 'dark' ? '0px 4px 4px rgba(0, 0, 0, 0.25)' : 'none' + }`, + width: '100%', + }, })) -export const FooterLinkWrapperLeft = styled(Box)(({ theme }) => ({ -})) +export const FooterLinkWrapperLeft = styled(Box)(({ theme }) => ({})) export const FooterLinkWrapper = styled(Box)(({ theme }) => ({ display: 'flex', @@ -102,14 +112,15 @@ export const FooterLinkWrapper = styled(Box)(({ theme }) => ({ justifyContent: 'space-between', alignItems: 'center', width: '70%', - margin: '20px auto', - [ theme.breakpoints.down('md') ]: { + margin: '32px auto', + [theme.breakpoints.down('md')]: { width: '100%', justifyContent: 'space-around', flexDirection: 'column', margin: '0', + marginTop: '20px', alignItems: 'flex-start', - } + }, })) export const LinkWrapper = styled(Box)(({ theme }) => ({ @@ -117,29 +128,42 @@ export const LinkWrapper = styled(Box)(({ theme }) => ({ width: '40%', justifyContent: 'flex-start', gap: '10px', - [ theme.breakpoints.down('md') ]: { + [theme.breakpoints.down('md')]: { flexDirection: 'column', alignItems: 'flex-start', - margin: '20px 0', + margin: '10px 0', + width: '100%', + gap: 0, + }, + [theme.breakpoints.down('sm')]: { + width: '100%', }, - [ theme.breakpoints.down('sm') ]: { - width: '100%' - } })) export const SocialWrapper = styled(Box)(({ theme }) => ({ display: 'flex', width: '20%', - justifyContent: 'flex-end', + justifyContent: 'flex-start', gap: '10px', - 'a': { + a: { cursor: 'pointer', }, - [ theme.breakpoints.down('md') ]: { - justifyContent: 'flex-start', + [theme.breakpoints.down('md')]: { + justifyContent: 'center', margin: '10px 0', + width: '100%', + }, + [theme.breakpoints.down('sm')]: { + width: '100%', + }, +})) + +export const SocialButton = styled(IconButton)(({ theme }) => ({ + opacity: 0.65, + '&:hover': { + background: 'none', + fill: theme.palette.primary.main, + color: theme.palette.primary.main, + opacity: 1, }, - [ theme.breakpoints.down('sm') ]: { - width: '100%' - } })) diff --git a/packages/boba/gateway/src/components/pageHeader/PageHeader.js b/packages/boba/gateway/src/components/pageHeader/PageHeader.js index eb4727f060..c36227d05c 100644 --- a/packages/boba/gateway/src/components/pageHeader/PageHeader.js +++ b/packages/boba/gateway/src/components/pageHeader/PageHeader.js @@ -7,7 +7,15 @@ import LayerSwitcher from 'components/mainMenu/layerSwitcher/LayerSwitcher' import ThemeSwitcher from 'components/mainMenu/themeSwitcher/ThemeSwitcher' import FeeSwitcher from 'components/mainMenu/feeSwitcher/FeeSwitcher' import { useState } from 'react' -import { Box, Container, Drawer, IconButton, Typography, useMediaQuery, useTheme } from '@mui/material' +import { + Box, + Container, + Drawer, + IconButton, + Typography, + useMediaQuery, + useTheme, +} from '@mui/material' import NavIcon from 'components/icons/NavIcon' import WalletIcon from 'components/icons/WalletIcon' import CloseIcon from 'components/icons/CloseIcon' @@ -15,30 +23,37 @@ import networkService from 'services/networkService' import { makeStyles } from '@mui/styles' import Copy from 'components/copy/Copy' import { useSelector } from 'react-redux' -import { selectAccountEnabled, selectMonster } from 'selectors/setupSelector' +import { + selectAccountEnabled, + selectLayer, + selectMonster, +} from 'selectors/setupSelector' +import NetworkSwitcher from 'components/mainMenu/networkSwitcher/NetworkSwitcher' +import WalletSwitch from 'components/walletSwitch/WalletSwitch' +import { LAYER } from 'util/constant' const useStyles = makeStyles({ root: { - width: "100%", - color: "f00", + width: '100%', + color: 'f00', }, }) const PageHeader = ({ maintenance }) => { - const classes = useStyles() // eslint-disable-next-line no-unused-vars - const [ open, setOpen ] = useState() - const [ walletOpen, setWalletOpen ] = useState() - const [ feeOpen, setFeeOpen ] = useState() + const [open, setOpen] = useState() + const [walletOpen, setWalletOpen] = useState() + const [feeOpen, setFeeOpen] = useState() const theme = useTheme() const accountEnabled = useSelector(selectAccountEnabled()) + const layer = useSelector(selectLayer()) const monsterNumber = useSelector(selectMonster()) const isMobile = useMediaQuery(theme.breakpoints.down('md')) let Logo = BobaLogo - if(monsterNumber>0) Logo = BobaLogoM + if (monsterNumber > 0) Logo = BobaLogoM if (maintenance) { return ( @@ -51,77 +66,114 @@ const PageHeader = ({ maintenance }) => { return ( <> - { - isMobile ? ( - - - - - setFeeOpen(!feeOpen)} sx={{ cursor: 'pointer' }}> - Fee - - setWalletOpen(!walletOpen)} sx={{ cursor: 'pointer' }}> - - - setOpen(!open)} sx={{ cursor: 'pointer' }}> - - - - setOpen(false)} classes={{ paper: classes.root }}> - - - - Menu - setOpen(false)}> - - - - - - - - - - setWalletOpen(false)} classes={{ paper: classes.root }}> - - - - Connect wallet - setWalletOpen(false)}> - - - - - - - - - setFeeOpen(false)} classes={{ paper: classes.root }}> - - - - Select Fee - setFeeOpen(false)}> - - - - - - - - - - - ) - : ( - - - - - {!!accountEnabled ? : null} - - ) - } + {isMobile ? ( + + + + + setFeeOpen(!feeOpen)} + sx={{ cursor: 'pointer' }} + > + + Fee + + + setWalletOpen(!walletOpen)} + sx={{ cursor: 'pointer' }} + > + + + setOpen(!open)} sx={{ cursor: 'pointer' }}> + + + + setOpen(false)} + classes={{ paper: classes.root }} + > + + + + + Menu + + setOpen(false)}> + + + + + + + + + + setWalletOpen(false)} + classes={{ paper: classes.root }} + > + + + + + Connect wallet + + setWalletOpen(false)} + > + + + + + + + + + setFeeOpen(false)} + classes={{ paper: classes.root }} + > + + + + + Select Fee + + setFeeOpen(false)}> + + + + + + {layer === LAYER.L2 ? ( + + ) : null} + + + + + ) : ( + + + + {layer === LAYER.L2 ? : null} + + + {!!accountEnabled ? ( + + ) : null} + + + )} ) } diff --git a/packages/boba/gateway/src/components/seven/FastExit.js b/packages/boba/gateway/src/components/seven/FastExit.js index 93ea6bab8b..0aba0b2171 100644 --- a/packages/boba/gateway/src/components/seven/FastExit.js +++ b/packages/boba/gateway/src/components/seven/FastExit.js @@ -18,9 +18,8 @@ import React from 'react' import { Typography } from '@mui/material' import * as S from './Transaction.styles' -import { selectNetwork } from 'selectors/setupSelector' -import { useSelector } from 'react-redux' -import { getNetwork } from 'util/masterConfig' + +import networkService from 'services/networkService' function FastExit({ link, @@ -33,13 +32,10 @@ function FastExit({ unixTime }) { - const currentNetwork = useSelector(selectNetwork()) - const nw = getNetwork() const chainLink = ({hash}) => { - let network = nw[currentNetwork] - if (!!network && !!network['L2']) { - return `${network['L2'].transaction}${hash}` + if (networkService.networkConfig[ 'L2' ]) { + return `${networkService.networkConfig['L2'].transaction}${hash}` } return '' } diff --git a/packages/boba/gateway/src/components/seven/Seven.js b/packages/boba/gateway/src/components/seven/Seven.js index 71a8ca28b0..83b80e7d2d 100644 --- a/packages/boba/gateway/src/components/seven/Seven.js +++ b/packages/boba/gateway/src/components/seven/Seven.js @@ -18,9 +18,8 @@ import React from 'react' import { Typography } from '@mui/material' import * as S from './Transaction.styles' -import { selectNetwork } from 'selectors/setupSelector' -import { useSelector } from 'react-redux' -import { getNetwork } from 'util/masterConfig' + +import networkService from 'services/networkService' function Seven({ link, @@ -33,13 +32,10 @@ function Seven({ unixTime }) { - const currentNetwork = useSelector(selectNetwork()) - const nw = getNetwork() const chainLink = ({hash}) => { - let network = nw[currentNetwork] - if (!!network && !!network['L2']) { - return `${network['L2'].transaction}${hash}` + if (networkService.networkConfig[ 'L2' ]) { + return `${networkService.networkConfig['L2'].transaction}${hash}` } return '' } diff --git a/packages/boba/gateway/src/components/showMoreShowLess/ShowMoreShowLess.js b/packages/boba/gateway/src/components/showMoreShowLess/ShowMoreShowLess.js new file mode 100644 index 0000000000..baf67aea08 --- /dev/null +++ b/packages/boba/gateway/src/components/showMoreShowLess/ShowMoreShowLess.js @@ -0,0 +1,35 @@ +import React, { useState } from 'react' +import { Typography } from '@mui/material'; + +const ShowMoreShowLess = ({ + children, + limit = 50, + sx +}) => { + const text = children; + + const [ showMore, setshowMore ] = useState(false); + + return ( + + {showMore ? text : text.substr(0, limit)} + {text.length > limit ? + setshowMore(!showMore)} + > + {showMore ? 'show less' : '... show more'} + + : null} + + ) + +} + +export default ShowMoreShowLess diff --git a/packages/boba/gateway/src/components/tabs/Tabs.styles.js b/packages/boba/gateway/src/components/tabs/Tabs.styles.js index 5c630f7a3c..d0bf0af7a0 100644 --- a/packages/boba/gateway/src/components/tabs/Tabs.styles.js +++ b/packages/boba/gateway/src/components/tabs/Tabs.styles.js @@ -1,35 +1,42 @@ -import styled from '@emotion/styled'; -import {Box} from '@mui/material'; +import styled from '@emotion/styled' +import { Box } from '@mui/material' -export const Tabs = styled(Box)(({theme})=>({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'flex-start', - flex: 1, - marginBottom: '20px', - borderBottom: theme.palette.primary.borderBottom, - [theme.breakpoints.down('md')]:{ - width: '100%' - } -})); +export const Tabs = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + flex: 1, + marginBottom: '20px', + borderBottom: theme.palette.primary.borderBottom, + [theme.breakpoints.down('md')]: { + width: '100%', + }, +})) export const TabItem = styled(Box)(({ theme }) => ({ - opacity: 0.7, - transition: 'color 200ms ease-in-out', - cursor: 'pointer', - marginRight: '20px', - '&:hover': { - opacity: 1, - }, - '&.active': { - color: `${theme.palette.mode === 'light' ? theme.palette.primary.main : theme.palette.neutral.main }`, - opacity: 1, - borderBottom: theme.palette.primary.tabBorderBottom, - marginBottom: '-2px', - zIndex: 1, - }, - [theme.breakpoints.down('md')]: { - flex: 1, - textAlign: 'center' - } + opacity: 0.7, + transition: 'color 200ms ease-in-out', + cursor: 'pointer', + marginRight: '20px', + textTransform: 'capitalize', + '&:hover': { + opacity: 1, + }, + '&.active': { + color: `${ + theme.palette.mode === 'light' + ? theme.palette.primary.main + : theme.palette.neutral.main + }`, + opacity: 1, + borderBottom: theme.palette.primary.tabBorderBottom, + marginBottom: '-2px', + zIndex: 1, + borderImage: 'linear-gradient(87.16deg, #CBFE00 15.05%, #1CD6D1 79.66%);', + borderImageSlice: 1, + }, + [theme.breakpoints.down('md')]: { + flex: 1, + textAlign: 'center', + }, })) diff --git a/packages/boba/gateway/src/components/tooltip/Tooltip.js b/packages/boba/gateway/src/components/tooltip/Tooltip.js index a8042c9f28..c8e7adcd54 100644 --- a/packages/boba/gateway/src/components/tooltip/Tooltip.js +++ b/packages/boba/gateway/src/components/tooltip/Tooltip.js @@ -1,25 +1,20 @@ -import React from 'react'; -import { Tooltip as MuiTooltip } from '@mui/material'; +import React from 'react' +import { Tooltip as MuiTooltip } from '@mui/material' +import * as styles from './Tooltip.module.scss' -import * as styles from './Tooltip.module.scss'; - -function Tooltip ({ - title, - arrow = true, - children -}) { - return ( - - {title} -
- } - arrow={arrow} - > - {children} - - ); +function Tooltip({ title, arrow = true, children }) { + if (title) { + return ( + {title}
} + arrow={arrow} + > + {children} + + ) + } else { + return children + } } -export default React.memo(Tooltip); +export default React.memo(Tooltip) diff --git a/packages/boba/gateway/src/components/tooltip/Tooltip.module.scss b/packages/boba/gateway/src/components/tooltip/Tooltip.module.scss index 7c93d6d7b0..9af7c22391 100644 --- a/packages/boba/gateway/src/components/tooltip/Tooltip.module.scss +++ b/packages/boba/gateway/src/components/tooltip/Tooltip.module.scss @@ -1,6 +1,6 @@ .title { font-size: 14px; - padding: 10px; - background: 'rgba(255, 255, 255, 0.06)'; - border-radius: '12px'; + padding: 13px 16px 12px; + border-radius: 12px; + color: rgba(255, 255, 255, 0.85); } diff --git a/packages/boba/gateway/src/components/transaction/Transaction.js b/packages/boba/gateway/src/components/transaction/Transaction.js index dc50c1d9f4..981257f017 100644 --- a/packages/boba/gateway/src/components/transaction/Transaction.js +++ b/packages/boba/gateway/src/components/transaction/Transaction.js @@ -18,13 +18,12 @@ import React, { useState } from 'react' import { Typography, Fade, useMediaQuery } from '@mui/material' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' -import * as S from "./ListFarm.styles" +import * as S from './ListFarm.styles' import { useTheme } from '@emotion/react' -import { selectNetwork } from 'selectors/setupSelector' -import { useSelector } from 'react-redux' -import { getNetwork } from 'util/masterConfig' + import truncate from 'truncate-middle' +import networkService from 'services/networkService' function Transaction({ link, @@ -45,27 +44,23 @@ function Transaction({ completion = '', tx_ref = null, eventType, - toChain + toChain, }) { - const [dropDownBox, setDropDownBox] = useState(false) const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down('md')) + const isNotFullScreen = useMediaQuery(theme.breakpoints.down(1920)) - const currentNetwork = useSelector(selectNetwork()) - const nw = getNetwork() - - const chainLink = ({chain,hash}) => { - let network = nw[currentNetwork] + const chainLink = ({ chain, hash }) => { + const network = networkService.networkConfig if (!!network && !!network[chain]) { - return `${network[chain].transaction}${hash}`; + return `${network[chain].transaction}${hash}` } return '' } function renderDetailRedesign() { - if (!detail) { return null } @@ -76,43 +71,94 @@ function Transaction({ return ( - - - - {prefix} Hash:  - + - {isMobile ? truncate(detail.hash, 6, 6, '...') : detail.hash} - - - - {prefix} Block: {detail.blockNumber} - {prefix} Block Hash:  - - {detail.blockHash} - - {prefix} From:  - - {detail.from} - - {prefix} To:  - - {detail.to} - + {prefix} Hash:  + + {isMobile ? truncate(detail.hash, 6, 6, '...') : detail.hash} + + + + + {prefix} Block: {detail.blockNumber} + + + {prefix} Block Hash:  + + {detail.blockHash} + + + + {prefix} From:  + + {detail.from} + + + + {prefix} To:  + + {detail.to} + + ) - } return ( - - + - - -
- {chain} - {time} - {completion === '' && -   - } - {completion !== '' && - {completion} - } - {toChain && - {toChain} - } - + +
+ + {chain} + + + {time} + + {completion === '' && ( + +   + + )} + {completion !== '' && ( + + {completion} + + )} + {toChain && ( + + {toChain} + + )} + {oriChain} Hash:  - {isMobile ? truncate(oriHash, 6, 6, '...') : oriHash} + {isNotFullScreen ? truncate(oriHash, 6, 6, '...') : oriHash}
-
+ - -
- - {blockNumber} - - - {typeTX} - - {eventType ? - {eventType} - : null} - {amountTx ? - - {amountTx} - : null - } -
-
- - - {!!detail && - {setDropDownBox(!dropDownBox)}} + +
- More Information - - } - - + + {blockNumber} + + + {typeTX} + + {eventType ? ( + + {eventType} + + ) : null} + {amountTx ? ( + + {amountTx} + + ) : null} +
+
- {dropDownBox ? renderDetailRedesign() : null } + + {!!detail && ( + { + setDropDownBox(!dropDownBox) + }} + > + More Information{' '} + + + )} + + + {dropDownBox ? renderDetailRedesign() : null} ) } diff --git a/packages/boba/gateway/src/components/walletSwitch/WalletSwitch.js b/packages/boba/gateway/src/components/walletSwitch/WalletSwitch.js new file mode 100644 index 0000000000..1a8f7788c0 --- /dev/null +++ b/packages/boba/gateway/src/components/walletSwitch/WalletSwitch.js @@ -0,0 +1,69 @@ +import React, { useEffect, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; + +import { setActiveNetwork } from 'actions/networkAction'; +import { setBaseState, setConnect, setConnectBOBA, setConnectETH, setEnableAccount } from 'actions/setupAction'; +import { selectActiveNetwork, selectActiveNetworkType, selectNetwork, selectNetworkType } from 'selectors/networkSelector'; + +import Button from 'components/button/Button'; +import { FiberManualRecord } from '@mui/icons-material'; +import { selectBaseEnabled, selectLayer } from 'selectors/setupSelector'; +import { LAYER } from 'util/constant'; + +const WalletSwitch = () => { + + const dispatch = useDispatch(); + const network = useSelector(selectNetwork()); + const activeNetwork = useSelector(selectActiveNetwork()); + const networkType = useSelector(selectNetworkType()); + const activeNetworkType = useSelector(selectActiveNetworkType()); + const layer = useSelector(selectLayer()); + const baseEnabled = useSelector(selectBaseEnabled()); + + const [ reconnect, setReconnect ] = useState(false); + + const onSwitch = () => { + dispatch(setActiveNetwork()); + // reset baseState to false to trigger initialization on chain change. + // and trigger the connect to BOBA & ETH base on current chain. + dispatch(setBaseState(false)); + dispatch(setEnableAccount(false)); + setReconnect(true); + } + + useEffect(() => { + if (!!reconnect && !!baseEnabled) { + + if (layer === LAYER.L1) { + dispatch(setConnectETH(true)); + } else if (layer === LAYER.L2) { + dispatch(setConnectBOBA(true)); + } else { + dispatch(setConnect(true)); + } + // set reconnect to false to avoid retrigger! + setReconnect(false); + } + }, [ layer, reconnect, baseEnabled, dispatch ]); + + if (activeNetwork === network + && activeNetworkType === networkType) { + return null; + } + + return <> + + +} + +export default WalletSwitch; diff --git a/packages/boba/gateway/src/containers/Global.styles.js b/packages/boba/gateway/src/containers/Global.styles.js index 47aa51e223..978eeaead7 100644 --- a/packages/boba/gateway/src/containers/Global.styles.js +++ b/packages/boba/gateway/src/containers/Global.styles.js @@ -54,9 +54,9 @@ export const LayerAlert = styled(Box)(({ theme }) => ({ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', - border: theme.palette.primary.border, + border: 'none', borderRadius: theme.palette.primary.borderRadius, - background: theme.palette.background.secondary, + background: theme.palette.background.alert, [ theme.breakpoints.up('md') ]: { width: '100%', }, diff --git a/packages/boba/gateway/src/containers/bridge/Bridge.js b/packages/boba/gateway/src/containers/bridge/Bridge.js index bbb55061ca..74099af828 100644 --- a/packages/boba/gateway/src/containers/bridge/Bridge.js +++ b/packages/boba/gateway/src/containers/bridge/Bridge.js @@ -1,6 +1,7 @@ import { Typography, useMediaQuery, useTheme } from '@mui/material' import React from 'react' import { useSelector } from 'react-redux' +import { selectActiveNetwork } from 'selectors/networkSelector' import { selectAccountEnabled } from 'selectors/setupSelector' import BobaBridge from './bobaBridge/bobaBridge' import * as S from './Bridge.styles' @@ -11,6 +12,8 @@ function BridgeContainer() { const accountEnabled = useSelector(selectAccountEnabled()) const isMobile = useMediaQuery(theme.breakpoints.down('sm')) + const activeNetwork = useSelector(selectActiveNetwork()) + return ( @@ -18,13 +21,13 @@ function BridgeContainer() { isMobile && accountEnabled ? null : - Transfer
- tokens between Ethereum and + tokens between {activeNetwork} and
({ margin: '20px auto', display: 'flex', @@ -22,6 +21,17 @@ export const PageContainer = styled(Box)(({ theme }) => ({ width: '100%', padding: '0px', }, + '::after': { + content: '" "', + position: 'absolute', + left: '-5%', + bottom: '10%', + width: '130%', + height: '100%', + background: `url(${bobaBridgeBg}) no-repeat`, + backgroundSize: '85%', + zIndex: '-1', + } })); @@ -63,22 +73,11 @@ export const TitleContainer = styled(Box)(({ theme }) => ({ position: 'absolute', top: '5%', right: '25%', - width: '50px', - height: '50px', + width: '80px', + height: '80px', background: `url(${bobaGlassIcon}) no-repeat`, backgroundSize: '100% 90%', }, - '::after': { - content: '" "', - position: 'absolute', - bottom: '20%', - left: 0, - width: '90%', - height: '100%', - background: `url(${bobaGlassBg}) no-repeat`, - backgroundSize: '100%', - zIndex: '-1' - } })) export const Content = styled(Box)(({ theme }) => ({ diff --git a/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.js b/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.js index 5cca7a7b65..3c76220071 100644 --- a/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.js +++ b/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.js @@ -1,4 +1,3 @@ - /* Utility Functions for OMG Plasma Copyright (C) 2021 Enya Inc. Palo Alto, CA @@ -18,12 +17,10 @@ */ import React, { useState } from 'react' -import { useDispatch, useSelector } from "react-redux" - -import { Box, Typography, Switch, useTheme } from "@mui/material" +import { useDispatch, useSelector } from 'react-redux' +import { useNavigate } from 'react-router-dom' -import BobaIcon from 'components/icons/BobaIcon.js' -import EthereumIcon from 'components/icons/EthereumIcon.js' +import { Box, Typography, Switch, useTheme } from '@mui/material' import Button from 'components/button/Button.js' import AvailableBridges from 'components/availableBridges/availableBridges.js' @@ -32,40 +29,52 @@ import * as S from './bobaBridge.styles' import BridgeTransfer from './bridgeTransfer/bridgeTransfer' import { selectAccountEnabled, selectLayer } from 'selectors/setupSelector' -import { selectBridgeTokens, selectMultiBridgeMode } from "selectors/bridgeSelector" +import { + selectBridgeTokens, + selectMultiBridgeMode, +} from 'selectors/bridgeSelector' +import { + selectActiveNetworkIcon, + selectActiveNetworkName, +} from 'selectors/networkSelector' -import { resetToken, setMultiBridgeMode } from "actions/bridgeAction" +import { resetToken, setMultiBridgeMode } from 'actions/bridgeAction' import { setConnectETH, setConnectBOBA } from 'actions/setupAction' -import { useNavigate } from 'react-router-dom' -function BobaBridge() { +import { L1_ICONS, L2_ICONS } from 'util/network/network.util' + +import { DEFAULT_NETWORK, LAYER } from 'util/constant' +function BobaBridge() { const layer = useSelector(selectLayer()) const accountEnabled = useSelector(selectAccountEnabled()) const multibridgeMode = useSelector(selectMultiBridgeMode()) const tokens = useSelector(selectBridgeTokens()) + const networkName = useSelector(selectActiveNetworkName()) + const icon = useSelector(selectActiveNetworkIcon()) + + const L1Icon = L1_ICONS[icon] + const L2Icon = L2_ICONS[icon] + const dispatch = useDispatch() - const [ toL2, setToL2 ] = useState(true) + const [toL2, setToL2] = useState(true) const theme = useTheme() const iconColor = theme.palette.mode === 'dark' ? '#fff' : '#000' const navigate = useNavigate() - async function connectToETH () { + async function connectToETH() { dispatch(setConnectETH(true)) } - async function connectToBOBA () { + async function connectToBOBA() { dispatch(setConnectBOBA(true)) } - async function switchDirection () { - console.log("layer:",layer) - if(accountEnabled) { - if(layer === 'L1') - dispatch(setConnectBOBA(true)) - else - dispatch(setConnectETH(true)) + async function switchDirection() { + if (accountEnabled) { + if (layer === LAYER.L1) dispatch(setConnectBOBA(true)) + else dispatch(setConnectETH(true)) } else { setToL2(!toL2) } @@ -75,29 +84,74 @@ function BobaBridge() { return ( - Bridge + + Bridge + Select the bridge direction + - - + + + + From + - From Ethereum + + + {networkName['l1'] || DEFAULT_NETWORK.NAME.L1} + - {switchDirection()}}> - - + { + switchDirection() + }} + > + + + + To + - To Boba + + + {networkName['l2'] || DEFAULT_NETWORK.NAME.L2} + - + @@ -106,29 +160,74 @@ function BobaBridge() { return ( - Bridge + + Bridge + Select the bridge direction + - - + + + + From + - From Boba + + + {networkName['l2'] || DEFAULT_NETWORK.NAME.L2} + - {switchDirection()}}> - - + { + switchDirection() + }} + > + + + + To + - To Ethereum + + + {networkName['l1'] || DEFAULT_NETWORK.NAME.L1} + - + @@ -138,93 +237,127 @@ function BobaBridge() { return ( <> - + - - {layer === 'L1' ? - From Ethereum - : - From Boba - } + + From + + + {layer === 'L1' ? ( + + + {networkName['l1'] || DEFAULT_NETWORK.NAME.L1} + + ) : ( + + + {networkName['l2'] || DEFAULT_NETWORK.NAME.L2} + + )} - - { switchDirection() }}> - - + + { + switchDirection() + }} + > + + + + To + - {layer === 'L2' ? - To Ethereum - : - To Boba - } + {layer === 'L2' ? ( + + + {networkName['l1'] || DEFAULT_NETWORK.NAME.L1} + + ) : ( + + + {networkName['l2'] || DEFAULT_NETWORK.NAME.L2} + + )} - - {layer === 'L1' && !multibridgeMode && tokens.length < 1 && - - - Bridge multiple tokens at once? - - + + Bridge multiple tokens at once? + + { - if (multibridgeMode) { - dispatch(resetToken()) - } - dispatch(setMultiBridgeMode(!multibridgeMode)) - }} - /> - - } - - + }} + onChange={() => { + if (multibridgeMode) { + dispatch(resetToken()) + } + dispatch(setMultiBridgeMode(!multibridgeMode)) + }} + /> + + )} + - - {tokens.length === 1 && - - } - + {tokens.length === 1 && } { navigate('/history') }} - display="flex" justifyContent="center"> - - {"Transaction History >"} + display="flex" + justifyContent="center" + > + + {'Transaction History >'} diff --git a/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.styles.js b/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.styles.js index 7b863d7631..64fdd059c0 100644 --- a/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.styles.js +++ b/packages/boba/gateway/src/containers/bridge/bobaBridge/bobaBridge.styles.js @@ -1,40 +1,59 @@ -import styled from '@emotion/styled'; -import { Box, Button, Divider as MuiDivider, IconButton, Typography } from "@mui/material"; +import styled from '@emotion/styled' +import { + Box, + Button, + Divider as MuiDivider, + IconButton, + Typography, +} from '@mui/material' export const BobaBridgeWrapper = styled(Box)(({ theme, width }) => ({ - background: theme.palette.background.secondary, - backdropFilter: 'blur(100px)', - borderRadius: theme.palette.primary.borderRadius, - border: theme.palette.primary.border, + background: theme.palette.background.glassy, + backdropFilter: 'blur(50px)', + borderRadius: theme.palette.secondary.borderRadius, flex: 1, minHeight: 'fit-content', - padding: '20px', + padding: '24px', width: '100%', + maxWidth: '600px', })) export const BobaContent = styled(Box)(({ theme }) => ({ display: 'flex', alignItems: 'center', justifyContent: 'space-between', - gap: '10px' + gap: '10px', })) -export const BobaContentWrapper = styled(Box)(({ theme, flexDirection }) => ({ +export const BridgeConnectButton = styled(Box)(({theme})=> ({ + alignSelf: 'flex-start', + [ theme.breakpoints.down('md') ]: { + alignSelf: 'stretch', + 'button': { + width: '100%' + } + } +})); + +export const BobaContentWrapper = styled(Box, { + shouldForwardProp: (props) => props !== 'fullWidth', +})(({ theme, flexDirection }) => ({ display: 'flex', justifyContent: 'space-between', flexDirection: flexDirection || 'column', - flexGrow: 1 + flexGrow: 1, })) -export const Divider = styled(MuiDivider)(({ theme }) => ({ +export const BobaDivider = styled(MuiDivider)(({ theme }) => ({ background: theme.palette.background.secondary, boxSizing: 'border-box', - width: '100%' + width: '100%', + margin: '32px 0 32px 0', })) export const ChainInput = styled(Box)(({ theme }) => ({ - background: theme.palette.background.secondary, - border: theme.palette.primary.border, + background: theme.palette.background.input, + border: theme.palette.secondary.border, boxSizing: 'border-box', borderRadius: theme.palette.primary.borderRadius, height: '50px', @@ -45,12 +64,12 @@ export const ChainInput = styled(Box)(({ theme }) => ({ gap: '10px', width: '100%', minWidth: '180px', - [ theme.breakpoints.down('sm') ]: { + [theme.breakpoints.down('sm')]: { justifyContent: 'flex-start', gap: '5px', padding: '5px 10px', - minWidth: '120px' - } + minWidth: '120px', + }, })) export const ChainLabel = styled(Typography)(({ theme }) => ({ @@ -58,15 +77,15 @@ export const ChainLabel = styled(Typography)(({ theme }) => ({ justifyContent: 'center', alignItems: 'center', gap: '10px', - [ theme.breakpoints.down('sm') ]: { + [theme.breakpoints.down('sm')]: { fontSize: '14px', - } + }, })) export const ChainSwitcherIcon = styled(Button)(({ theme }) => ({ margin: '20px 0px', width: 'fit-content', - alignSelf: 'center' + alignSelf: 'center', })) export const HistoryLink = styled(Box)(({ theme, width }) => ({ @@ -74,14 +93,15 @@ export const HistoryLink = styled(Box)(({ theme, width }) => ({ borderRadius: theme.palette.primary.borderRadius, border: theme.palette.primary.border, width: '100%', - padding: '10px', + maxWidth: '600px', + padding: '20px', '&:hover > span': { - color: theme.palette.secondary.main - } + color: theme.palette.secondary.main, + }, })) export const LayerAlert = styled(Box)(({ theme }) => ({ - width: "100%", + width: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', @@ -93,14 +113,12 @@ export const LayerAlert = styled(Box)(({ theme }) => ({ [theme.breakpoints.up('md')]: { padding: '25px 50px', }, - })) export const AlertText = styled(Typography)(({ theme }) => ({ marginLeft: '10px', flex: 4, - [theme.breakpoints.up('md')]: { - }, + [theme.breakpoints.up('md')]: {}, })) export const AlertInfo = styled(Box)` @@ -108,16 +126,15 @@ export const AlertInfo = styled(Box)` justify-content: space-around; align-items: center; flex: 1; -`; +` export const IconSwitcher = styled(IconButton)(({ theme }) => ({ - background: theme.palette.background.secondary, - border: theme.palette.primary.border, + background: theme.palette.background.input, borderRadius: theme.palette.primary.borderRadius, height: '40px', width: '40px', display: 'flex', alignSelf: 'center', justifyContent: 'center', - alignItems: 'center' + alignItems: 'center', })) diff --git a/packages/boba/gateway/src/containers/bridge/bobaBridge/bridgeTransfer/bridgeTransfer.js b/packages/boba/gateway/src/containers/bridge/bobaBridge/bridgeTransfer/bridgeTransfer.js index d5589a83ca..389e62c112 100644 --- a/packages/boba/gateway/src/containers/bridge/bobaBridge/bridgeTransfer/bridgeTransfer.js +++ b/packages/boba/gateway/src/containers/bridge/bobaBridge/bridgeTransfer/bridgeTransfer.js @@ -30,6 +30,7 @@ import DoExitStep from 'containers/modals/exit/steps/DoExitStep' import InputStep from 'containers/modals/deposit/steps/InputStep' import InputStepBatch from 'containers/modals/deposit/steps/InputStepBatch' import { fetchLookUpPrice } from 'actions/networkAction' +import { LAYER } from 'util/constant' function BridgeTransfer() { @@ -43,7 +44,6 @@ function BridgeTransfer() { const dispatch = useDispatch() const onReset = () => { - console.log([`RESET TOKEN onReset`]) dispatch(resetToken()) } @@ -101,10 +101,10 @@ function BridgeTransfer() { } {tokens.length > 0 && !multibridgeMode && <> - {layer === 'L1' && + {layer === LAYER.L1 && } - {layer === 'L2' && + {layer === LAYER.L2 && } diff --git a/packages/boba/gateway/src/containers/connect/Connect.js b/packages/boba/gateway/src/containers/connect/Connect.js index 4a9010115d..46d1dd06f2 100644 --- a/packages/boba/gateway/src/containers/connect/Connect.js +++ b/packages/boba/gateway/src/containers/connect/Connect.js @@ -1,59 +1,57 @@ -import React from "react" +import React from 'react' import * as G from '../Global.styles' -import { useDispatch } from "react-redux" +import { useDispatch } from 'react-redux' import AlertIcon from 'components/icons/AlertIcon' import Button from 'components/button/Button.js' -import { - setConnectBOBA, - setConnect -} from 'actions/setupAction' - -const Connect = ({ userPrompt, accountEnabled, connectToBoba = false, layer = '' }) => { +import { setConnectBOBA, setConnect } from 'actions/setupAction' +const Connect = ({ + userPrompt, + accountEnabled, + connectToBoba = false, + layer = '', +}) => { const dispatch = useDispatch() - if(!accountEnabled && !connectToBoba) { + if (!accountEnabled && !connectToBoba) { return ( - - - - - {userPrompt} - - - - + {userPrompt} + + + + ) - } - else if (layer !== 'L2' && connectToBoba) { + } else if (layer !== 'L2' && connectToBoba) { return ( - + - + {userPrompt} @@ -62,7 +60,6 @@ const Connect = ({ userPrompt, accountEnabled, connectToBoba = false, layer = '' } return null - } export default Connect diff --git a/packages/boba/gateway/src/containers/devtools/TxBuilder.js b/packages/boba/gateway/src/containers/devtools/TxBuilder.js index af48ff2663..d31a8c562a 100644 --- a/packages/boba/gateway/src/containers/devtools/TxBuilder.js +++ b/packages/boba/gateway/src/containers/devtools/TxBuilder.js @@ -9,12 +9,10 @@ import Button from 'components/button/Button' import { openError } from 'actions/uiAction' import { selectTxBuilder } from 'selectors/devToolsSelector' -import { selectNetwork, selectLayer } from 'selectors/setupSelector' +import { selectLayer } from 'selectors/setupSelector' import { submitTxBuilder, resetTxBuilder } from 'actions/devToolsAction' -import { getNetwork } from 'util/masterConfig' - import networkService from 'services/networkService' import * as S from './TxBuilder.styles' @@ -25,10 +23,7 @@ const TxBuilder = () => { const TxBuilderResult = useSelector(selectTxBuilder, shallowEqual) const networkLayer = useSelector(selectLayer()) - const nw = getNetwork() - const masterConfig = useSelector(selectNetwork()) - const blockexploerUrl = nw[masterConfig].L2.blockExplorer - + const blockExplorerUrl = networkService.networkConfig.L2.blockExplorer const [ contractAddress, setContractAddress ] = useState('') const [ contractABI, setContractABI ] = useState('') const [ contractMethos, setContractMethods ] = useState([]) @@ -214,7 +209,7 @@ const TxBuilder = () => { Succeeded! - ) + + ) } return ( <> - {!isBridge && - + {!isBridge && ( + Fast Bridge to L2 - } + )} { + onChange={(i) => { setAmount(i.target.value) setValue_Wei_String(toWei_String(i.target.value, token.decimals)) }} - onUseMax={(i)=>{//they want to use the maximum + onUseMax={(i) => { + //they want to use the maximum setAmount(maxValue) //so the input value updates for the user setValue_Wei_String(token.balance.toString()) }} @@ -339,51 +340,59 @@ function InputStepFast({ handleClose, token, isBridge, openTokenPicker }) { - - - - {(Number(LPRatio) < 0.10 && Number(value) > Number(balanceSubPending) * 0.90) && ( - - The {token.symbol} pool's balance and balance/liquidity ratio are low. - Please use the classic bridge. - - )} - - {(Number(LPRatio) < 0.10 && Number(value) <= Number(balanceSubPending) * 0.90) && ( - - The {token.symbol} pool's balance/liquidity ratio (of {Number(LPRatio).toFixed(2)}) is too low. - Please use the classic bridge. - - )} - - {(Number(LPRatio) >= 0.10 && Number(value) > Number(balanceSubPending) * 0.90) && ( - - The {token.symbol} pool's balance (of {Number(balanceSubPending).toFixed(2)} including inflight bridges) is too low. - Please use the classic bridge or reduce the amount. - - )} + {Number(LPRatio) < 0.1 && + Number(value) > Number(balanceSubPending) * 0.9 && ( + + The {token.symbol} pool's balance and balance/liquidity ratio are + low. Please use the classic bridge. + + )} + + {Number(LPRatio) < 0.1 && + Number(value) <= Number(balanceSubPending) * 0.9 && ( + + The {token.symbol} pool's balance/liquidity ratio (of{' '} + {Number(LPRatio).toFixed(2)}) is too low. Please use the classic + bridge. + + )} + + {Number(LPRatio) >= 0.1 && + Number(value) > Number(balanceSubPending) * 0.9 && ( + + The {token.symbol} pool's balance (of{' '} + {Number(balanceSubPending).toFixed(2)} including inflight bridges) + is too low. Please use the classic bridge or reduce the amount. + + )} {warning && ( - + {parse(ETHstring)} )} {!!token && token.symbol === 'OMG' && ( - - The OMG Token was minted in 2017 and it does not conform to the ERC20 token standard. - In some cases, three interactions with MetaMask are needed. + + The OMG Token was minted in 2017 and it does not conform to the + ERC20 token standard. In some cases, three interactions with + MetaMask are needed. )} - {!isBridge && (depositLoading || approvalLoading) && ( - - This window will automatically close when your transaction has been signed and submitted. + {!isBridge && (depositLoading || approvalLoading) && ( + + This window will automatically close when your transaction has been + signed and submitted. )} @@ -392,18 +401,22 @@ function InputStepFast({ handleClose, token, isBridge, openTokenPicker }) { @@ -353,7 +361,7 @@ class FarmDepositModal extends React.Component { {stakeValueValid && allowanceGTstake && <> - {stakeToken.symbol !== 'ETH' && + {stakeToken.symbol !== netLayerNativeToken && Your allowance has been approved. You can now stake your funds. @@ -361,8 +369,9 @@ class FarmDepositModal extends React.Component { diff --git a/packages/boba/gateway/src/containers/modals/farm/FarmWithdrawModal.js b/packages/boba/gateway/src/containers/modals/farm/FarmWithdrawModal.js index 87d2404e8a..552c65a46d 100644 --- a/packages/boba/gateway/src/containers/modals/farm/FarmWithdrawModal.js +++ b/packages/boba/gateway/src/containers/modals/farm/FarmWithdrawModal.js @@ -235,8 +235,9 @@ class FarmWithdrawModal extends React.Component { diff --git a/packages/boba/gateway/src/containers/modals/noMetaMask/InstallMetaMaskModal/InstallMetaMaskModal.js b/packages/boba/gateway/src/containers/modals/noMetaMask/InstallMetaMaskModal/InstallMetaMaskModal.js new file mode 100644 index 0000000000..be0c69aed5 --- /dev/null +++ b/packages/boba/gateway/src/containers/modals/noMetaMask/InstallMetaMaskModal/InstallMetaMaskModal.js @@ -0,0 +1,76 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; + +import { Box, Typography } from '@mui/material' +import { Circle } from '@mui/icons-material' + +import { closeModal } from 'actions/uiAction'; +import { setConnect } from 'actions/setupAction'; + +import Button from 'components/button/Button'; +import Modal from 'components/modal/Modal'; + +function InstallMetaMaskModal({open}) { + + const dispatch = useDispatch(); + + const handleClose = () => { + dispatch(closeModal('installMetaMaskModal')); + dispatch(setConnect(false)); + } + + const handleRefresh = () => { + handleClose(); + window.location.reload(); + } + + return ( + + + + + Install the MetaMask extension + + + We recommend pinning MetaMask to your taskbar for quicker access to your wallet. + + + + + Create New Wallet Or Import Wallet + + + Never share your secret phrase with anyone. + + + + + Refresh your browser + + + Once you are done with setting up wallet, click below refresh button to load up the extensions and access gateway. + + + + + + + + ) +} + +export default React.memo(InstallMetaMaskModal); diff --git a/packages/boba/gateway/src/containers/modals/noMetaMask/NoMetaMaskModal.js b/packages/boba/gateway/src/containers/modals/noMetaMask/NoMetaMaskModal.js new file mode 100644 index 0000000000..6a6563317b --- /dev/null +++ b/packages/boba/gateway/src/containers/modals/noMetaMask/NoMetaMaskModal.js @@ -0,0 +1,50 @@ +import React from 'react'; +import { useDispatch } from 'react-redux'; + +import { Box } from '@mui/material'; + +import { closeModal, openModal } from 'actions/uiAction'; +import Button from 'components/button/Button'; +import Modal from 'components/modal/Modal'; +import { MM_EXTENTION_URL } from 'util/constant'; +import { setConnect } from 'actions/setupAction'; + +function NoMetaMaskModal({open}) { + + const dispatch = useDispatch(); + + const handleClose = () => { + dispatch(closeModal('noMetaMaskModal')); + dispatch(setConnect(false)); + } + + const handleAddMetaMask = () => { + window.open(MM_EXTENTION_URL, '_blank'); + dispatch(openModal('installMetaMaskModal')); + handleClose() + } + + return ( + + + + + + ) +} + +export default React.memo(NoMetaMaskModal); diff --git a/packages/boba/gateway/src/containers/modals/transfer/TransferModal.js b/packages/boba/gateway/src/containers/modals/transfer/TransferModal.js index eaa456914b..5766132f8a 100644 --- a/packages/boba/gateway/src/containers/modals/transfer/TransferModal.js +++ b/packages/boba/gateway/src/containers/modals/transfer/TransferModal.js @@ -197,7 +197,7 @@ function TransferModal ({ open, token, minHeight }) { {fee && !feeUseBoba && ( - Fee: {fee} ETH + Fee: {fee} {networkService.L1NativeTokenSymbol} )} @@ -224,8 +224,9 @@ function TransferModal ({ open, token, minHeight }) { {!isMobile ? ( diff --git a/packages/boba/gateway/src/containers/modals/transfer/TransferNFTModal.js b/packages/boba/gateway/src/containers/modals/transfer/TransferNFTModal.js index 77879d5f4d..3777c1154d 100644 --- a/packages/boba/gateway/src/containers/modals/transfer/TransferNFTModal.js +++ b/packages/boba/gateway/src/containers/modals/transfer/TransferNFTModal.js @@ -91,8 +91,9 @@ function TransferNFTModal ({ open, token, minHeight }) { {!isMobile ? ( diff --git a/packages/boba/gateway/src/containers/modals/wrongNetwork/WrongNetworkModal.js b/packages/boba/gateway/src/containers/modals/wrongNetwork/WrongNetworkModal.js index 53d68b4c6e..a124b69872 100644 --- a/packages/boba/gateway/src/containers/modals/wrongNetwork/WrongNetworkModal.js +++ b/packages/boba/gateway/src/containers/modals/wrongNetwork/WrongNetworkModal.js @@ -1,17 +1,20 @@ -import { Box, Typography } from '@mui/material'; +import { Box } from '@mui/material'; +import { setConnect, setConnectETH } from 'actions/setupAction'; import { closeModal } from 'actions/uiAction'; +import Button from 'components/button/Button'; import Modal from 'components/modal/Modal'; import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { selectNetwork } from 'selectors/setupSelector'; +import { selectNetwork } from 'selectors/networkSelector'; function WrongNetworkModal({open}) { const dispatch = useDispatch(); const network = useSelector(selectNetwork()); - function handleClose () { + function handleClose() { + dispatch(setConnect(false)); dispatch(closeModal('wrongNetworkModal')); } @@ -20,14 +23,19 @@ function WrongNetworkModal({open}) { open={open} onClose={handleClose} maxWidth="xs" - minHeight="200px" + minHeight="180px" title="Wrong Network" newStyle={true} > - - Please connect to the {network} network - + ) diff --git a/packages/boba/gateway/src/containers/save/Save.js b/packages/boba/gateway/src/containers/save/Save.js index a95a5817c3..dc9cef4b79 100644 --- a/packages/boba/gateway/src/containers/save/Save.js +++ b/packages/boba/gateway/src/containers/save/Save.js @@ -147,7 +147,7 @@ class Save extends React.Component { if (netLayer === 'L2') { let cost_BN = await networkService.savingEstimate() - console.log([ `cost_BN`, cost_BN ]) + if (bobaFeeChoice) { // we are staking BOBA and paying in BOBA // so need to subtract the BOBA fee @@ -296,7 +296,7 @@ class Save extends React.Component { disabled={netLayer !== 'L2'} variant="standard" /> - + {netLayer === 'L2' && bobaFeeChoice && fee && Fee: {fee} BOBA diff --git a/packages/boba/gateway/src/containers/wallet/Wallet.js b/packages/boba/gateway/src/containers/wallet/Wallet.js index a33bef15db..6c8b84bfcd 100644 --- a/packages/boba/gateway/src/containers/wallet/Wallet.js +++ b/packages/boba/gateway/src/containers/wallet/Wallet.js @@ -1,9 +1,9 @@ -import React, { useEffect, useState } from "react" +import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import Button from 'components/button/Button' -import { Info } from "@mui/icons-material" +import { Info } from '@mui/icons-material' import { Box, Icon, Typography } from '@mui/material' import { getETHMetaTransaction } from 'actions/setupAction' @@ -13,123 +13,115 @@ import { fetchTransactions } from 'actions/networkAction' import Tabs from 'components/tabs/Tabs' import Nft from 'containers/wallet/nft/Nft' import Token from './token/Token' -import Connect from 'containers/connect/Connect' import * as S from './wallet.styles' import * as G from '../Global.styles' -import { - setConnectETH, - setConnectBOBA -} from 'actions/setupAction' +import { setConnectETH, setConnectBOBA } from 'actions/setupAction' -import { - selectAccountEnabled, - selectLayer, -} from "selectors/setupSelector" +import { selectAccountEnabled, selectLayer } from 'selectors/setupSelector' import { selectlayer2Balance } from 'selectors/balanceSelector' -import PageTitle from 'components/pageTitle/PageTitle' import { isEqual } from 'lodash' -import { POLL_INTERVAL } from "util/constant" -import useInterval from "hooks/useInterval" +import { DEFAULT_NETWORK, LAYER, POLL_INTERVAL } from 'util/constant' +import useInterval from 'hooks/useInterval' import BN from 'bignumber.js' import { logAmount } from 'util/amountConvert.js' +import { + selectActiveNetwork, + selectActiveNetworkName, +} from 'selectors/networkSelector' +import networkService from 'services/networkService' +import { NETWORK } from 'util/network/network.util' +import Connect from "../connect/Connect"; +import PageTitle from "../../components/pageTitle/PageTitle"; function Wallet() { - - const [ page, setPage ] = useState('Token') - const [ chain, setChain ] = useState('') - const [ tooSmallETH, setTooSmallETH ] = useState(false) - const [ tooSmallBOBA, setTooSmallBOBA ] = useState(false) + const [page, setPage] = useState('Token') + const [tooSmallSec, setTooSmallSec] = useState(false) + const [tooSmallBOBA, setTooSmallBOBA] = useState(false) const dispatch = useDispatch() - + const network = useSelector(selectActiveNetwork()) const layer = useSelector(selectLayer()) const accountEnabled = useSelector(selectAccountEnabled()) - + const networkName = useSelector(selectActiveNetworkName()) // low balance warnings const l2Balances = useSelector(selectlayer2Balance, isEqual) - useEffect(()=>{ - if (accountEnabled) - dispatch(fetchTransactions()) - },[ dispatch, accountEnabled ]) + // fetching transactions + useEffect(() => { + if (accountEnabled) dispatch(fetchTransactions()) + }, [dispatch, accountEnabled]) - useEffect(()=>{ - if (accountEnabled && l2Balances.length > 0) { + useInterval(() => { + if (accountEnabled) { + dispatch(fetchTransactions()) + } + }, POLL_INTERVAL) - const l2BalanceETH = l2Balances.find((i) => i.symbol === 'ETH') + useEffect(() => { + if (accountEnabled && l2Balances.length > 0) { + const l2BalanceSec = l2Balances.find( + (i) => i.symbol === networkService.L1NativeTokenSymbol + ) const l2BalanceBOBA = l2Balances.find((i) => i.symbol === 'BOBA') - if (l2BalanceETH && l2BalanceETH.balance) { - setTooSmallETH(new BN(logAmount(l2BalanceETH.balance, 18)).lt(new BN(0.003))) + if (l2BalanceSec && l2BalanceSec.balance) { + // FOR ETH MIN BALANCE 0.003ETH for other sec tokens 1 + const minBalance = network === NETWORK.ETHEREUM ? 0.003 : 1 + setTooSmallSec( + new BN(logAmount(l2BalanceSec.balance, 18)).lt(new BN(minBalance)) + ) } else { - // in case of zero ETH balance we are setting tooSmallETH - setTooSmallETH(true) + // in case of zero ETH balance we are setting tooSmallSec + setTooSmallSec(true) } if (l2BalanceBOBA && l2BalanceBOBA.balance) { - setTooSmallBOBA(new BN(logAmount(l2BalanceBOBA.balance, 18)).lt(new BN(4.0))) + // FOR BOBA MIN BALANCE of 1 + setTooSmallBOBA( + new BN(logAmount(l2BalanceBOBA.balance, 18)).lt(new BN(1)) + ) } else { // in case of zero BOBA balance we are setting tooSmallBOBA setTooSmallBOBA(true) } } - },[ l2Balances, accountEnabled ]) + }, [l2Balances, accountEnabled, network]) useEffect(() => { if (layer === 'L2') { - if (tooSmallBOBA && tooSmallETH) { - dispatch(openError('Wallet empty - please bridge in ETH or BOBA from L1')) + if (tooSmallBOBA && tooSmallSec) { + dispatch( + openError( + `Wallet empty - please bridge in ${networkService.L1NativeTokenSymbol} or BOBA from L1` + ) + ) } } - },[tooSmallETH, tooSmallBOBA, layer, dispatch]) - - useInterval(() => { - if (accountEnabled) { - dispatch(fetchTransactions()) - } - }, POLL_INTERVAL) - - useEffect(() => { - if (layer === 'L2') { - setChain('Boba Wallet') - } else if (layer === 'L1') { - setChain('Ethereum Wallet') - } - }, [ layer ]) - - const handleSwitch = (l) => { - if (l === 'Token') { - setPage('Token') - } else if (l === 'NFT') { - setPage('NFT') - } - } + }, [tooSmallSec, tooSmallBOBA, layer, dispatch]) - async function emergencySwap () { + async function emergencySwap() { const res = await dispatch(getETHMetaTransaction()) - console.log("emergencySwap - res:",res) - if (res) dispatch(openAlert('Emergency Swap submitted')) + if (res) { + dispatch(openAlert('Emergency Swap submitted')) + } } return ( - - - - {layer === 'L2' && tooSmallETH && - + {layer === 'L2' && tooSmallSec && ( + - + - Using Boba requires a minimum ETH balance (of 0.002 ETH) regardless of your fee setting, - otherwise MetaMask may incorrectly reject transactions. If you ran out of ETH, use - EMERGENCY SWAP to swap BOBA for 0.005 ETH at market rates. + Using {networkService.L1NativeTokenSymbol} requires a minimum BOBA + balance (of 1 BOBA) regardless of your fee setting, otherwise + MetaMask may incorrectly reject transactions. If you ran out of + BOBA, use EMERGENCY SWAP to swap{' '} + {networkService.L1NativeTokenSymbol} for 1 BOBA at market rates. + - } + )} - - - { - if (!!accountEnabled) { - dispatch(setConnectETH(true)) - } - }} - variant="body2" - component="span"> - Ethereum Wallet - - { - if (!!accountEnabled) { - dispatch(setConnectBOBA(true)) - } - }} - variant="body2" - component="span"> - Boba Wallet + {accountEnabled ? ( + + + { + if (!!accountEnabled) { + dispatch(setConnectETH(true)) + } + }} + variant="body2" + component="span" + > + {networkName['l1'] || DEFAULT_NETWORK.NAME.L1} Wallet + + { + if (!!accountEnabled) { + dispatch(setConnectBOBA(true)) + } + }} + variant="body2" + component="span" + > + {networkName['l2'] || DEFAULT_NETWORK.NAME.L2} Wallet + + + + + + + Connected - - - - - handleSwitch(t)} - aria-label="Page Tab" - tabs={[ "Token", "NFT" ]} - /> - - {page === 'Token' ? : } + + ) : ( + + + + + Disconnected + + )} + + {accountEnabled ? ( + <> + {network === NETWORK.ETHEREUM ? ( + <> + + setPage(t)} + aria-label="Page Tab" + tabs={['Token', 'NFT']} + /> + + {page === 'Token' ? : } + + ) : ( + + )} + + ) : ('')} + + ) } diff --git a/packages/boba/gateway/src/containers/wallet/nft/Nft.js b/packages/boba/gateway/src/containers/wallet/nft/Nft.js index 3960e0e046..be0227ae9c 100644 --- a/packages/boba/gateway/src/containers/wallet/nft/Nft.js +++ b/packages/boba/gateway/src/containers/wallet/nft/Nft.js @@ -16,69 +16,39 @@ import BobaGlassIcon from 'components/icons/BobaGlassIcon' import Connect from 'containers/connect/Connect' class Nft extends React.Component { - constructor(props) { - super(props) - const { - list, - monsterNumber, - monsterInfo - } = this.props.nft + const { list } = this.props.nft - const { - accountEnabled, - netLayer, - network, - walletAddress - } = this.props.setup + const { accountEnabled, netLayer, network, walletAddress } = + this.props.setup this.state = { list, contractAddress: '', tokenID: '', - loading: this.props.loading[ 'NFT/ADD' ], + loading: this.props.loading['NFT/ADD'], accountEnabled, netLayer, network, walletAddress, - monsterNumber, - monsterInfo } - } componentDidUpdate(prevState) { + const { list } = this.props.nft - const { - list, - monsterNumber, - monsterInfo - } = this.props.nft - - const { - accountEnabled, - netLayer, - network, - walletAddress - } = this.props.setup + const { accountEnabled, netLayer, network, walletAddress } = + this.props.setup if (!isEqual(prevState.nft.list, list)) { this.setState({ list }) } - if (!isEqual(prevState.nft.monsterNumber, monsterNumber)) { - this.setState({ monsterNumber }) - } - - if (!isEqual(prevState.nft.monsterInfo, monsterInfo)) { - this.setState({ monsterInfo }) - } - - if (!isEqual(prevState.loading[ 'NFT/ADD' ], this.props.loading[ 'NFT/ADD' ])) { - this.setState({ loading: this.props.loading[ 'NFT/ADD' ] }) - if (this.props.loading[ 'NFT/ADD' ]) { + if (!isEqual(prevState.loading['NFT/ADD'], this.props.loading['NFT/ADD'])) { + this.setState({ loading: this.props.loading['NFT/ADD'] }) + if (this.props.loading['NFT/ADD']) { this.setState({ contractAddress: '' }) } } @@ -98,14 +68,13 @@ class Nft extends React.Component { if (!isEqual(prevState.setup.walletAddress, walletAddress)) { this.setState({ walletAddress }) } - } - handleInputAddress = event => { + handleInputAddress = (event) => { this.setState({ contractAddress: event.target.value }) } - handleInputID = event => { + handleInputID = (event) => { this.setState({ tokenID: event.target.value }) } @@ -118,7 +87,6 @@ class Nft extends React.Component { } render() { - const { list, contractAddress, @@ -131,7 +99,6 @@ class Nft extends React.Component { } = this.state if (!netLayer) { - return ( @@ -139,26 +106,22 @@ class Nft extends React.Component { sx={{ display: 'flex', flexDirection: 'column', - alignItems: 'center' + alignItems: 'center', }} > - - - - - No Data - + ) - } else if (netLayer === 'L1') { return ( ) - } - - else { - + } else { return ( @@ -177,50 +137,55 @@ class Nft extends React.Component { - - Add NFT - + Add NFT -
Monsters can be autoadded to your wallet +
+ Monsters can be autoadded to your wallet
- + Other NFTs must be added manually - } - - } - - {layer === 'L2' && network === 'goerli' && - - - - - - Developer Twitter/Turing test token fountain - your Boba Bubble:{" "} - {BT} - - - - - Welcome developers. - For testnet BOBA and ETH, tweet your Boba Bubble and - then paste the tweet link in the field below. + <> + {layer === 'L2' && network === 'mainnet' && ( + + + Need ETH or BOBA + {'? '} + + You can swap one for the other at{' '} + + + Sushiswap + + + and + + Oolongswap + + {debug && ( + + )} + + )} - Tweet Now - - - - For the Tweet link, tap the share icon, tap "Share Tweet via", and finally select "Copy link to Tweet". - - - setTweetUrl(e?.target?.value.split('?')[0])} //remove the superfluous stuff after the "?" - /> - - - You are limited to one fountain call per twitter account per day. - The transaction will not show in your history since it's a MetaTransaction (the gas is covered by Boba). - + - - - {faucetErrorMsg ? {faucetErrorMsg} : null} + Bridge in progress:{' '} + Click for detailed status + + - - } - - {!!accountEnabled && inflight.length > 0 && - - { - dispatch(setActiveHistoryTab("Pending")); - navigate('/history') - }} - > - Bridge in progress:{' '} - Click for detailed status - - - - } - - - - - {tokenTableHeads.map((item) => { - return ( - {item.label} + )} + + + + + {tokenTableHeads.map((item) => { + return ( + + {item.label} + + ) + })} + + {layer === 'L2' ? ( + !balanceLoading || !!l2Balance.length ? ( + l2Balance.map((i) => { + return ( + + ) + }) + ) : ( + + + ) - })} - - {networkLayer === 'L2' ? !balanceLoading || !!childBalance.length ? childBalance.map((i, index) => { - return ( - - ) - }) : - - - : null} - {networkLayer === 'L1' ? !balanceLoading || !!rootBalance.length ? rootBalance.map((i, index) => { - return ( - - ) - }) : - - - : null} - - - ) + ) : null} + {layer === 'L1' ? ( + !balanceLoading || !!l1Balance.length ? ( + l1Balance.map((i) => { + return ( + + ) + }) + ) : ( + + + + ) + ) : null} + +
+ + ) } - } export default React.memo(TokenPage) diff --git a/packages/boba/gateway/src/containers/wallet/wallet.styles.js b/packages/boba/gateway/src/containers/wallet/wallet.styles.js index a8bf8efd8f..4ddda72f5d 100644 --- a/packages/boba/gateway/src/containers/wallet/wallet.styles.js +++ b/packages/boba/gateway/src/containers/wallet/wallet.styles.js @@ -9,49 +9,50 @@ export const PageContainer = styled(Box)(({ theme }) => ({ padding: '10px', paddingTop: '0px', width: '70%', - [ theme.breakpoints.between('md', 'lg') ]: { + [theme.breakpoints.between('md', 'lg')]: { width: '90%', padding: '0px', }, - [ theme.breakpoints.between('sm', 'md') ]: { + [theme.breakpoints.between('sm', 'md')]: { width: '90%', padding: '0px', }, - [ theme.breakpoints.down('sm') ]: { + [theme.breakpoints.down('sm')]: { width: '100%', padding: '0px', }, -})); +})) export const WalletTitleContainer = styled(Box)(({ theme }) => ({ display: 'flex', alignItems: 'center', justifyContent: 'flex-start', gap: '20px', - [ theme.breakpoints.down('md') ]: { - margin: '10px 0px' - } -})); + [theme.breakpoints.down('md')]: { + margin: '10px 0px', + }, +})) export const WalletActionContainer = styled(Box)(({ theme }) => ({ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '20px', - marginBottom: '20px', - [ theme.breakpoints.down('sm') ]: { + marginBottom: '10px', + marginTop: '10px', + [theme.breakpoints.down('sm')]: { flexDirection: 'column', alignItems: 'flex-start', }, -})); +})) export const PendingIndicator = styled(Box)(({ theme }) => ({ display: 'flex', justifyContent: 'flex-start', alignItems: 'center', gap: '20px', - [ theme.breakpoints.down('sm') ]: { + [theme.breakpoints.down('sm')]: { alignItems: 'flex-start', - margin: '10px 0px' + margin: '10px 0px', }, -})) \ No newline at end of file +})) diff --git a/packages/boba/gateway/src/hooks/useNetwork.js b/packages/boba/gateway/src/hooks/useNetwork.js new file mode 100644 index 0000000000..24ce8ef41d --- /dev/null +++ b/packages/boba/gateway/src/hooks/useNetwork.js @@ -0,0 +1,48 @@ +/* +Copyright 2021-present Boba Network. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +import { setNetwork } from 'actions/networkAction'; +import { useEffect } from 'react'; +import { useDispatch } from 'react-redux'; +import { useSearchParams } from 'react-router-dom'; +import { CHAIN_ID_LIST, NetworkList } from 'util/network/network.util'; + +const useNetwork = () => { + const [ searchParams ] = useSearchParams(); + const dispatch = useDispatch(); + + useEffect(() => { + const queryParams = Object.fromEntries([ ...searchParams ]) + if (queryParams.chainId) { + const { + chain, + networkType + } = CHAIN_ID_LIST[ queryParams.chainId || 1 ] + + const { name, icon } = NetworkList[ networkType ].filter((n) => n.chain === chain)[ 0 ]; + + dispatch(setNetwork({ + networkType, + name, + network: chain, + networkIcon: icon, + })); + } + }, [ searchParams, dispatch ]); + +} + + +export default useNetwork; diff --git a/packages/boba/gateway/src/images/moonbase.png b/packages/boba/gateway/src/images/moonbase.png new file mode 100644 index 0000000000..e4961a5a62 Binary files /dev/null and b/packages/boba/gateway/src/images/moonbase.png differ diff --git a/packages/boba/gateway/src/images/mtt.png b/packages/boba/gateway/src/images/mtt.png new file mode 100644 index 0000000000..042a149d75 Binary files /dev/null and b/packages/boba/gateway/src/images/mtt.png differ diff --git a/packages/boba/gateway/src/index.js b/packages/boba/gateway/src/index.js index cc63b32f2f..95906da54f 100644 --- a/packages/boba/gateway/src/index.js +++ b/packages/boba/gateway/src/index.js @@ -16,7 +16,8 @@ limitations under the License. */ import React from 'react' import ReactDOM from 'react-dom' import { Provider } from 'react-redux' -import store from 'store' +import { store, persistor } from 'store' +import {PersistGate} from 'redux-persist/integration/react' import App from 'layout' import './index.scss' import SentryWrapper from 'components/SentryWrapper/SentryWrapper' @@ -27,10 +28,12 @@ if (window.ethereum) { } ReactDOM.render( - - - - - , + + + + + + + , document.getElementById('root') ) diff --git a/packages/boba/gateway/src/layout/index.js b/packages/boba/gateway/src/layout/index.js index 1741ceab67..e2c735d55d 100644 --- a/packages/boba/gateway/src/layout/index.js +++ b/packages/boba/gateway/src/layout/index.js @@ -15,46 +15,34 @@ limitations under the License. */ import React, { Suspense, useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { BrowserRouter } from 'react-router-dom' import { Box, useMediaQuery } from '@mui/material' import CssBaseline from '@mui/material/CssBaseline' -import { createTheme, responsiveFontSizes, ThemeProvider } from '@mui/material/styles' +import { + createTheme, + responsiveFontSizes, + ThemeProvider, +} from '@mui/material/styles' import { setTheme } from 'actions/uiAction' +import { selectModalState } from 'selectors/uiSelector' -import Home from 'containers/home/Home' import Notification from 'containers/notification/Notification' -import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom" -import { selectModalState } from 'selectors/uiSelector' - -import Transactions from 'containers/history/History' -import BobaScope from 'containers/bobaScope/BobaScope' -import Help from 'containers/help/Help' -import Ecosystem from 'containers/ecosystem/Ecosystem' -import Wallet from 'containers/wallet/Wallet' -import Bridge from 'containers/bridge/Bridge' -import MonsterWrapper from 'containers/monster/MonsterWrapper' -import Lock from 'containers/veboba/Lock' -import FarmWrapper from 'containers/farm/FarmWrapper' -import SaveWrapper from 'containers/save/SaveWrapper' -import Projects from 'containers/ecosystem/Projects' -import { DISABLE_VE_DAO, ROUTES_PATH } from 'util/constant' -import VoteAndDao from 'containers/VoteAndDao' -import OldDao from 'containers/dao/OldDao' -import DevTools from 'containers/devtools/DevTools' +import Router from './routes' function App() { - const dispatch = useDispatch() const theme = useSelector(selectModalState('theme')) const light = theme === 'light' const radioGreen = '#BAE21A' - const buttonColor = '#228fe5' //blue const darkGrey = '#1b1c1f' + const buttonColor = '#BAE21A' //radioGreen + let MUItheme = createTheme({ palette: { mode: theme === 'light' ? 'light' : 'dark', @@ -63,21 +51,36 @@ function App() { gradient: 'linear-gradient(131.81deg, #4A6FEF 2.66%, #4251F0 124.21%)', contrastText: '#fff', border: light ? 'solid 1px rgba(0, 0, 0, 0.12)' : 'solid 1px #2d2f3a', - borderRadius: '8px', - borderBottom: light ? 'solid 1px rgba(0, 0, 0, 0.08)' : '1px solid rgba(255, 255, 255, 0.04)', - tabBorderBottom: light ? `solid 2px ${buttonColor}}` : `2px solid ${buttonColor}}`, + borderRadius: '12px', + borderBottom: light + ? 'solid 1px rgba(0, 0, 0, 0.08)' + : '1px solid rgba(255, 255, 255, 0.04)', + tabBorderBottom: light + ? `solid 2px ${buttonColor}` + : `solid 2px ${buttonColor}`, + alert: light ? 'black' : '#FFD88D', }, secondary: { main: light ? buttonColor : buttonColor, + borderRadius: '20px', + border: light + ? 'solid 1px rgba(0, 0, 0, 0.12)' + : 'solid 1px rgba(255, 255, 255, 0.06)', }, background: { - default: light ? "#FFFFFF" : "#111315", + default: light ? '#FFFFFF' : '#111315', secondary: light ? 'rgba(0, 0, 0, 0.04)' : darkGrey, - secondaryLight: light ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.14)', + secondaryLight: light + ? 'rgba(0, 0, 0, 0.08)' + : 'rgba(255, 255, 255, 0.14)', dropdown: light ? '#dadada' : '#142031', - modal: light ? "#fff" : '#1A1D1F', - modalTransparent: light ? "#fff" : 'transparent', - input: light ? "rgba(0, 0, 0, 0.06)" : "rgba(255, 255, 255, 0.04)", + modal: light ? '#fff' : '#1A1D1F', + modalTransparent: light ? '#fff' : 'transparent', + input: light ? 'rgba(0, 0, 0, 0.06)' : 'rgba(255, 255, 255, 0.04)', + footer: light ? '#fff' : '#1A1D1F', + glassy: light ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.04)', + tooltip: light ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.06)', + alert: light ? 'rgba(3, 19, 19, 0.06)' : 'rgba(255, 216, 141, 0.1)', }, neutral: { main: '#fff', @@ -85,7 +88,7 @@ function App() { }, }, typography: { - fontFamily: [ "MrEavesXL", 'Roboto' ].join(','), + fontFamily: ['MrEavesXL', 'Roboto'].join(','), h1: { fontSize: 42, fontWeight: 700, @@ -104,21 +107,21 @@ function App() { }, body1: { fontSize: 18, - display: 'block' + display: 'block', }, body2: { fontSize: 16, fontWeight: 400, lineHeight: '1.0em', - display: 'block' + display: 'block', }, body3: { fontSize: 14, lineHeight: '1.1em', - display: 'block' + display: 'block', }, body4: { - fontSize: 12 + fontSize: 12, }, }, components: { @@ -130,19 +133,33 @@ function App() { root: {}, }, }, + MuiTooltip: { + styleOverrides: { + tooltip: { + backgroundColor: light + ? 'rgba(0, 0, 0, 0.08)' + : 'rgba(255, 255, 255, 0.06)', + backdropFilter: 'blur(50px)', + borderRadius: '12px', + }, + arrow: { + color: light ? 'rgba(0, 0, 0, 0.08)' : 'rgba(255, 255, 255, 0.06)', + }, + }, + }, MuiButton: { styleOverrides: { root: { - borderRadius: "8px", - textTransform: "none", - boxShadow: "box-shadow: 0px 0px 7px rgba(73, 107, 239, 0.35)", - minWidth: "0", + borderRadius: '8px', + textTransform: 'none', + boxShadow: 'box-shadow: 0px 0px 7px rgba(73, 107, 239, 0.35)', + minWidth: '0', color: '#031313', - "&.Mui-disabled": { + '&.Mui-disabled': { background: light ? 'transparent' : 'rgba(255, 255, 255, 0.04)', color: light ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)', border: light ? '1px solid rgba(0, 0, 0, 0.5)' : 'none', - } + }, }, }, variants: [ @@ -150,16 +167,18 @@ function App() { props: { variant: 'contained', color: 'primary' }, style: { // background: 'linear-gradient(131.81deg, #4A6FEF 2.66%, #4251F0 124.21%)', - background: buttonColor, + background: radioGreen, borderWidth: '1.4px', - borderColor: buttonColor, + borderColor: radioGreen, fontWeight: 500, - color: '#fff', - "&:hover": { + fontSize: '16px', + font: 'Roboto', + color: '#031313', + '&:hover': { boxShadow: 'inset 0px 0px 0px 3px rgba(255, 255, 255, 0.2)', transition: 'box-shadow 0.3s ease-in-out', - backgroundColor: buttonColor, - } + backgroundColor: radioGreen, + }, }, }, { @@ -170,66 +189,73 @@ function App() { background: light ? '#fff' : 'none', borderWidth: '1.4px', fontWeight: 700, - filter: "drop-shadow(0px 0px 3px rgba(73, 107, 239, 0.35))", - "&:hover": { + filter: 'drop-shadow(0px 0px 3px rgba(73, 107, 239, 0.35))', + '&:hover': { color: '#000', borderColor: buttonColor, backgroundColor: buttonColor, borderWidth: '1.4px', boxShadow: 'inset 2px 2px 13px rgba(0, 0, 0, 0.15)', - } + }, }, }, { props: { variant: 'standard', color: 'primary' }, style: { - color: light ? 'rgba(0, 0, 0, 0.45)' : 'rgba(255, 255, 255, 0.45)', - background: light ? 'rgba(0, 0, 0, 0.06)' : 'rgba(255, 255, 255, 0.06)', + color: light + ? 'rgba(0, 0, 0, 0.45)' + : 'rgba(255, 255, 255, 0.45)', + background: light + ? 'rgba(0, 0, 0, 0.06)' + : 'rgba(255, 255, 255, 0.06)', borderWidth: '1.4px', - borderColor: radioGreen, - filter: "drop-shadow(0px 0px 7px rgba(73, 107, 239, 0.35))", - "&:hover": { - color: radioGreen, - boxShadow: light ? 'none' : 'inset 2px 2px 13px rgba(0, 0, 0, 0.15)', - } + borderColor: buttonColor, + filter: 'drop-shadow(0px 0px 7px rgba(73, 107, 239, 0.35))', + '&:hover': { + color: buttonColor, + boxShadow: light + ? 'none' + : 'inset 2px 2px 13px rgba(0, 0, 0, 0.15)', + }, }, }, { props: { variant: 'contained', color: 'neutral' }, style: { - "&:hover": { + '&:hover': { opacity: 0.9, transition: 'opacity 0.3s ease-in-out', - } + }, }, }, { props: { variant: 'outlined', color: 'neutral' }, style: { - color: light ? "#000" : "rgba(255, 255, 255, 0.65)", + color: light ? '#000' : buttonColor, borderWidth: '1.4px', - borderColor: light ? "#000" : "rgba(255, 255, 255, 0.25)", - "&:hover": { + borderColor: light ? '#000' : 'rgba(255, 255, 255, 0.25)', + '&:hover': { opacity: 0.9, borderWidth: '1.4px', transition: 'opacity 0.3s ease-in-out', - borderColor: light ? "#000" : "#fff", + borderColor: light ? '#000' : buttonColor, boxShadow: 'inset 2px 2px 13px rgba(0, 0, 0, 0.15)', - } + }, }, }, { props: { variant: 'small' }, style: { fontSize: '14px', - background: 'linear-gradient(131.81deg, #4A6FEF 2.66%, #4251F0 124.21%)', + background: + 'linear-gradient(131.81deg, #4A6FEF 2.66%, #4251F0 124.21%)', textTransform: 'uppercase', borderRadius: '12px', minWidth: '0', - "&:hover": { + '&:hover': { boxShadow: 'inset 0px 0px 0px 2px rgba(255, 255, 255, 0.2)', transition: 'box-shadow 0.3s ease-in-out', - } + }, }, }, { @@ -247,7 +273,7 @@ function App() { ], }, MuiInputBase: { - backgroundColor: "#f00", + backgroundColor: '#f00', }, MuiAlert: { variants: [ @@ -255,13 +281,13 @@ function App() { props: { variant: 'simple' }, style: { padding: 0, - backgroundColor: 'transparent' - } - } - ] - } - } - }); + backgroundColor: 'transparent', + }, + }, + ], + }, + }, + }) MUItheme = responsiveFontSizes(MUItheme) @@ -270,51 +296,27 @@ function App() { useEffect(() => { const themeFromLocalStorage = localStorage.getItem('theme') dispatch(setTheme(themeFromLocalStorage)) - }, [ dispatch ]) - + }, [dispatch]) return ( - +
Loading...}> - - } > - } /> - } /> - } > - } /> - - } /> - } /> - } /> - } /> - - } /> - } /> - } /> - } > - } /> - - } /> - {/* FIXME: On setting flag below to 1 below routes will not be available to user. */} - {!Number(DISABLE_VE_DAO) && } />} - {!Number(DISABLE_VE_DAO) && } />} - } /> - } /> - - +
diff --git a/packages/boba/gateway/src/layout/routes/index.js b/packages/boba/gateway/src/layout/routes/index.js new file mode 100644 index 0000000000..a16dfe2319 --- /dev/null +++ b/packages/boba/gateway/src/layout/routes/index.js @@ -0,0 +1,43 @@ +import { useEffect, useState } from 'react'; +import { PAGES_BY_NETWORK } from 'util/constant' +import { COMMON_ROUTES, ROUTE_LIST } from './routeList' +import { useSelector } from 'react-redux'; +import { selectActiveNetwork } from 'selectors/networkSelector'; +import { useRoutes } from 'react-router-dom'; +import { intersection } from 'lodash'; + + +export const Router = () => { + + const routeList = ROUTE_LIST; + const [ routes, setRoutes ] = useState([]); + const network = useSelector(selectActiveNetwork()); + + useEffect(() => { + const childRoutes = routeList[ 0 ].children; + const fRoutes = childRoutes.filter((m) => intersection([ m.key ], PAGES_BY_NETWORK[ network.toLowerCase() ]).length); + const {path, ...indexRoute} = fRoutes[ 0 ]; + const _routes = [ + { + ...indexRoute, + index:true + }, + ...fRoutes, + ...COMMON_ROUTES + ].filter((r) => !r.disable) + + setRoutes([ + { + ...routeList[ 0 ], + children: _routes + } + ]); + return () => { + setRoutes(null) + }; + }, [ network, routeList ]); + + return useRoutes(routes); +} + +export default Router; diff --git a/packages/boba/gateway/src/layout/routes/routeList.js b/packages/boba/gateway/src/layout/routes/routeList.js new file mode 100644 index 0000000000..cf63d7e02e --- /dev/null +++ b/packages/boba/gateway/src/layout/routes/routeList.js @@ -0,0 +1,121 @@ +import React from 'react'; + +import { DISABLE_VE_DAO, ROUTES_PATH } from "util/constant"; + +import Bridge from "containers/bridge/Bridge"; +import Home from "containers/home/Home"; +import Projects from 'containers/ecosystem/Projects'; +import Ecosystem from 'containers/ecosystem/Ecosystem'; +import Wallet from 'containers/wallet/Wallet'; +import OldDao from 'containers/dao/OldDao'; +import History from 'containers/history/History'; +import FarmWrapper from 'containers/farm/FarmWrapper'; +import SaveWrapper from 'containers/save/SaveWrapper'; +import MonsterWrapper from 'containers/monster/MonsterWrapper'; +import { Navigate } from 'react-router-dom'; +import Lock from 'containers/veboba/Lock'; +import Vote from 'containers/VoteAndDao/Vote/Vote'; +import BobaScope from 'containers/bobaScope/BobaScope'; +import Help from 'containers/help/Help'; +import DevTools from 'containers/devtools/DevTools'; + +export const COMMON_ROUTES = [ + { + path: "*", + element: , + key: '', + }, + { + path: ROUTES_PATH.BOBASCOPE, + element: , + key: 'bobascope', + }, + { + path: ROUTES_PATH.DEV_TOOLS, + element: , + key: 'Devtool', + }, + { + path: ROUTES_PATH.HELP, + element: , + key: 'help', + } +] + +export const ROUTE_LIST = [ + { + path: '/', + element: , + children: [ + { + path: ROUTES_PATH.BRIDGE, + element: , + key: 'Bridge', + }, + { + path: ROUTES_PATH.WALLET, + element: , + key: 'Wallet', + }, + { + path: ROUTES_PATH.HISTORY, + element: , + key: 'History', + }, + { + path: ROUTES_PATH.EARN, + element: , + key: 'Earn', + }, + { + path: ROUTES_PATH.STAKE, + element: , + key: 'Stake', + }, + { + path: ROUTES_PATH.DAO, + element: , + key: 'DAO', + }, + { + path: ROUTES_PATH.LOCK, + element: , + key: 'DAO', + disable: !!Number(DISABLE_VE_DAO), + }, + { + path: ROUTES_PATH.VOTE_DAO, + element: , + key: 'DAO', + disable: !!Number(DISABLE_VE_DAO), + }, + { + path: ROUTES_PATH.MONSTER, + element: , + key: 'Monster', + }, + { + path: ROUTES_PATH.BOBA_CHAINS, + element: , + key: 'LinksToBobaChains', + children: [ + { + path: ':category', + element: + } + ] + }, + { + path: ROUTES_PATH.ECOSYSTEM, + element: , + key: 'Ecosystem', + children: [ + { + path: ':category', + element: + } + ] + } + ] + } +] diff --git a/packages/boba/gateway/src/reducers/exitReducer.js b/packages/boba/gateway/src/reducers/exitReducer.js deleted file mode 100644 index b53f74738a..0000000000 --- a/packages/boba/gateway/src/reducers/exitReducer.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2021-present Boba Network. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -import { keyBy } from 'lodash'; - -const initialState = { - pending: {}, - exited: {} -}; - -function exitReducer (state = initialState, action) { - switch (action.type) { - case 'EXIT/GETALL/SUCCESS': - // action.payload will be null on an event timeout, so return old state - if (!action.payload) { - return state; - } - return { ...state, ...action.payload }; - case 'EXIT/CREATE/SUCCESS': - return { - ...state, - }; - case 'EXIT/CHECKALL/SUCCESS': - return { - ...state, - pending: { - ...state.pending, - ...keyBy(action.payload, 'hash') - } - }; - default: - return state; - } -} - -export default exitReducer; diff --git a/packages/boba/gateway/src/reducers/index.js b/packages/boba/gateway/src/reducers/index.js index 31ec2fed46..9c496945a8 100644 --- a/packages/boba/gateway/src/reducers/index.js +++ b/packages/boba/gateway/src/reducers/index.js @@ -21,7 +21,6 @@ import transactionReducer from './transactionReducer' import dataReducer from './dataReducer' import statusReducer from './statusReducer' import balanceReducer from './balanceReducer' -import exitReducer from './exitReducer' import queueReducer from './queueReducer' import tokenReducer from './tokenReducer' import nftReducer from './nftReducer' @@ -38,6 +37,7 @@ import verifierReducer from './verifierReducer'; import bridgeReducer from './bridgeReducer'; import veBobaReducer from './veBobaReducer'; import devToolsReducer from './devToolsReducer'; +import networkReducer from './networkReducer'; const rootReducer = combineReducers({ loading: loadingReducer, @@ -47,7 +47,6 @@ const rootReducer = combineReducers({ signature: signatureReducer, status: statusReducer, balance: balanceReducer, - exit: exitReducer, queue: queueReducer, tokenList: tokenReducer, nft: nftReducer, @@ -63,6 +62,7 @@ const rootReducer = combineReducers({ bridge: bridgeReducer, veboba: veBobaReducer, devTools: devToolsReducer, + network: networkReducer }) export default rootReducer diff --git a/packages/boba/gateway/src/reducers/networkReducer.js b/packages/boba/gateway/src/reducers/networkReducer.js new file mode 100644 index 0000000000..41ed39cc46 --- /dev/null +++ b/packages/boba/gateway/src/reducers/networkReducer.js @@ -0,0 +1,78 @@ +/* +Copyright 2021-present Boba Network. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +import { NETWORK, NETWORK_TYPE } from "util/network/network.util" + +/** + * network : ethereum, bnb, fantom, avax, moonbase, moonbeam + * networkType : mainnet, testnet. + **/ + +/** + * NOTE: + * 3. enable switch once selected !== current. + * 4. on selection dispatch event. + * 5. on switch click dispatch event. and reload. + */ + +const initialState = { + network: NETWORK.ETHEREUM, + networkIcon: 'ethereum', + networkType: NETWORK_TYPE.MAINNET, + name: {}, + activeNetworkIcon: 'ethereum', + activeNetwork: NETWORK.ETHEREUM, + activeNetworkType: NETWORK_TYPE.MAINNET, + activeNetworkName: {}, +} + +function networkReducer(state = initialState, action) { + switch (action.type) { + case 'NETWORK/SET': { + const { + network, + networkType, + networkIcon, + name + } = action.payload; + return { + ...state, + network, + networkIcon, + networkType, + name + } + } + case 'NETWORK/SET/ACTIVE':{ + const { + network: activeNetwork, + networkType: activeNetworkType, + networkIcon: activeNetworkIcon, + name: activeNetworkName + } = state; + return { + ...state, + activeNetwork, + activeNetworkType, + activeNetworkIcon, + activeNetworkName + } + } + default: + return state + } +} + +export default networkReducer diff --git a/packages/boba/gateway/src/reducers/setupReducer.js b/packages/boba/gateway/src/reducers/setupReducer.js index 784bb1f1ce..e8781023ff 100644 --- a/packages/boba/gateway/src/reducers/setupReducer.js +++ b/packages/boba/gateway/src/reducers/setupReducer.js @@ -13,8 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -import { APP_CHAIN } from 'util/constant' - let justSwitchedChain = localStorage.getItem("justSwitchedChain") if (justSwitchedChain) { @@ -26,7 +24,6 @@ const initialState = { baseEnabled: null, netLayer: null, walletAddress: null, - network: APP_CHAIN, justSwitchedChain: justSwitchedChain ? justSwitchedChain : false, bobaFeePriceRatio: null, bobaFeeChoice: null, @@ -35,7 +32,7 @@ const initialState = { connect: false } -function setupReducer (state = initialState, action) { +function setupReducer(state = initialState, action) { switch (action.type) { case 'SETUP/ACCOUNT/SET': localStorage.setItem("justSwitchedChain", JSON.stringify(false)) @@ -55,16 +52,10 @@ function setupReducer (state = initialState, action) { baseEnabled: action.payload, } case 'SETUP/LAYER/SET': - console.log("SR: Setting layer to:", action.payload) return { ...state, netLayer: action.payload } - case 'SETUP/NETWORK/SET': - return { - ...state, - network: action.payload - } case 'SETUP/CONNECT_ETH': return { ...state, @@ -81,26 +72,29 @@ function setupReducer (state = initialState, action) { connect: action.payload } case 'SETUP/SWITCH/REQUEST': - console.log("SR:REQUEST - setting just changed to true") localStorage.setItem("justSwitchedChain", JSON.stringify(true)) return { ...state, justSwitchedChain: true } case 'SETUP/SWITCH/SUCCESS': - console.log("SR:SUCCESS - setting just changed to true") localStorage.setItem("justSwitchedChain", JSON.stringify(true)) return { ...state, justSwitchedChain: true } case 'BOBAFEE/ADD/SUCCESS': - console.log("BOBAFEE/ADD/SUCCESS:",action.payload) return { ...state, bobaFeePriceRatio: action.payload.priceRatio, bobaFeeChoice: action.payload.feeChoice } + case 'SETUP/APPCHAIN/SET': + return { + ...state, + appChain: action.payload, + network: action.payload + } default: return state } diff --git a/packages/boba/gateway/src/reducers/signatureReducer.js b/packages/boba/gateway/src/reducers/signatureReducer.js index 47b96eaa8d..a0c3b4a48e 100644 --- a/packages/boba/gateway/src/reducers/signatureReducer.js +++ b/packages/boba/gateway/src/reducers/signatureReducer.js @@ -16,36 +16,26 @@ limitations under the License. */ const initialState = { exitLPsigned: false, exitTRADsigned: false, - depositLPsigned: false, - depositTRADsigned: false + depositLPsigned: false } function signatureReducer (state = initialState, action) { switch (action.type) { case 'EXIT/LP/SIGNED': - console.log('exitLPsigned:',action.payload) return { ...state, exitLPsigned: action.payload } case 'EXIT/TRAD/SIGNED': - console.log('exitTRADsigned:',action.payload) return { ...state, exitTRADsigned: action.payload } case 'DEPOSIT/LP/SIGNED': - console.log('depositLPsigned:',action.payload) return { ...state, depositLPsigned: action.payload } - case 'DEPOSIT/TRAD/SIGNED': - console.log('depositTRADsigned:',action.payload) - return { - ...state, - depositTRADsigned: action.payload - } default: return state; } diff --git a/packages/boba/gateway/src/selectors/exitSelector.js b/packages/boba/gateway/src/selectors/exitSelector.js deleted file mode 100644 index 75bca8b658..0000000000 --- a/packages/boba/gateway/src/selectors/exitSelector.js +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2021-present Boba Network. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. */ - -export function selectPendingExits (state) { - return Object.values(state.exit.pending); -} - -export function selectExitedExits (state) { - return Object.values(state.exit.exited); -} diff --git a/packages/boba/gateway/src/selectors/networkSelector.js b/packages/boba/gateway/src/selectors/networkSelector.js new file mode 100644 index 0000000000..60ebf5c1d6 --- /dev/null +++ b/packages/boba/gateway/src/selectors/networkSelector.js @@ -0,0 +1,49 @@ +/* +Copyright 2021-present Boba Network. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +export function selectNetwork () { + return function (state) { + return state.network['network'] + } +} + +export function selectNetworkType() { + return function (state) { + return state.network['networkType'] + } +} + +export function selectActiveNetwork () { + return function (state) { + return state.network['activeNetwork'] + } +} + +export function selectActiveNetworkType() { + return function (state) { + return state.network['activeNetworkType'] + } +} + +export function selectActiveNetworkIcon() { + return function (state) { + return state.network['activeNetworkIcon'] + } +} +export function selectActiveNetworkName() { + return function (state) { + return state.network['activeNetworkName'] + } +} diff --git a/packages/boba/gateway/src/selectors/setupSelector.js b/packages/boba/gateway/src/selectors/setupSelector.js index fa8c839a4b..e365fa0f5e 100644 --- a/packages/boba/gateway/src/selectors/setupSelector.js +++ b/packages/boba/gateway/src/selectors/setupSelector.js @@ -33,13 +33,6 @@ export function selectBaseEnabled () { } } -// local, goerli, mainnet... -export function selectNetwork () { - return function (state) { - return state.setup['network'] - } -} - export function selectLayer () { return function (state) { return state.setup['netLayer'] @@ -93,3 +86,4 @@ export function selectMonsterInfo () { return state.nft['monsterInfo'] } } + diff --git a/packages/boba/gateway/src/selectors/signatureSelector.js b/packages/boba/gateway/src/selectors/signatureSelector.js index 8be9686193..2c08908511 100644 --- a/packages/boba/gateway/src/selectors/signatureSelector.js +++ b/packages/boba/gateway/src/selectors/signatureSelector.js @@ -24,7 +24,3 @@ export function selectSignatureStatus_exitTRAD (state) { export function selectSignatureStatus_depositLP (state) { return state.signature.depositLPsigned } - -export function selectSignatureStatus_depositTRAD (state) { - return state.signature.depositTRADsigned -} diff --git a/packages/boba/gateway/src/services/abi/BobaGasPriceOracle.abi.js b/packages/boba/gateway/src/services/abi/BobaGasPriceOracle.abi.js new file mode 100644 index 0000000000..fc097ef629 --- /dev/null +++ b/packages/boba/gateway/src/services/abi/BobaGasPriceOracle.abi.js @@ -0,0 +1,13 @@ +const BobaGasPriceOracleABI = [ + 'function secondaryFeeTokenMinimum() public view returns (uint256)', + 'function priceRatio() public view returns (uint256)', + 'function bobaFeeTokenUsers(address) public view returns (bool user)', + 'function secondaryFeeTokenUsers(address) public view returns (bool user)', + 'function getBOBAForSwap() public view returns (uint256)', + 'function getSecondaryFeeTokenForSwap() public view returns (uint256)', + 'function useBobaAsFeeToken() public', + 'function useETHAsFeeToken() public', + 'function useSecondaryFeeTokenAsFeeToken() public', +] + +export default BobaGasPriceOracleABI; diff --git a/packages/boba/gateway/src/services/abi/L1StandardBridge.abi.js b/packages/boba/gateway/src/services/abi/L1StandardBridge.abi.js new file mode 100644 index 0000000000..8bc8a62ca1 --- /dev/null +++ b/packages/boba/gateway/src/services/abi/L1StandardBridge.abi.js @@ -0,0 +1,10 @@ +const L1StandardBridgeABI = [ + 'function depositETH(uint32 _l2Gas, bytes calldata _data) external payable', + 'function depositETHTo(address _to, uint32 _l2Gas, bytes calldata _data) external payable', + 'function depositERC20(address _l1Token,address _l2Token, uint256 _amount, uint32 _l2Gas,bytes calldata _data) external', + 'function depositERC20To(address _l1Token, address _l2Token, address _to, uint256 _amount, uint32 _l2Gas,bytes calldata _data) external', + 'function depositNativeToken(uint32 _l2Gas, bytes calldata _data) external payable', + 'function depositNativeTokenTo(address _to,uint32 _l2Gas,bytes calldata _data) external payable' +] + +export default L1StandardBridgeABI; diff --git a/packages/boba/gateway/src/services/app.service.js b/packages/boba/gateway/src/services/app.service.js new file mode 100644 index 0000000000..9177f2711d --- /dev/null +++ b/packages/boba/gateway/src/services/app.service.js @@ -0,0 +1,268 @@ +import { NETWORK, NETWORK_TYPE } from "util/network/network.util"; +// testnet addresss +import addresses_Goerli from "@boba/register/addresses/addressesGoerli_0x6FF9c8FF8F0B6a0763a3030540c21aFC721A9148" +import addresses_BobaBase from "@boba/register/addresses/addressesBobaBase_0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B" +import addresses_BobaOperaTestnet from "@boba/register/addresses/addressesBobaOperaTestnet_0x12ad9f501149D3FDd703cC10c567F416B7F0af8b" +import addresses_BobaFuji from "@boba/register/addresses/addressBobaFuji_0xcE78de95b85212BC348452e91e0e74c17cf37c79" +import addresses_BobaBnbTestnet from "@boba/register/addresses/addressBobaBnbTestnet_0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa" + +// mainnet address +import addresses_Mainnet from "@boba/register/addresses/addressesMainnet_0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089" +import addresses_BobaBeam from "@boba/register/addresses/addressBobaBeam_0x564c10A60af35a07f0EA8Be3106a4D81014b21a0" +import addresses_BobaAvax from "@boba/register/addresses/addressBobaAvax_0x00220f8ce1c4be8436574e575fE38558d85e2E6b" +import addresses_BobaBnb from "@boba/register/addresses/addressBobaBnb_0xeb989B25597259cfa51Bd396cE1d4B085EC4c753" +import addresses_BobaOpera from "@boba/register/addresses/addressBobaOpera_0x4e7325bcf09e091Bb8119258B885D4ef687B7386" + +// layerzero addresses. +import layerZeroTestnet from "@boba/register/addresses/layerZeroTestnet" +import layerZeroMainnet from "@boba/register/addresses/layerZeroMainnet" +import store from "store"; + +// predeployed contracts. + +// const ERROR_ADDRESS = '0x0000000000000000000000000000000000000000' +const L1_ETH_Address = '0x0000000000000000000000000000000000000000' +const L2_BOBA_Address = '0x4200000000000000000000000000000000000006' +const L2MessengerAddress = '0x4200000000000000000000000000000000000007' +const L2StandardBridgeAddress = '0x4200000000000000000000000000000000000010' +// const L2GasOracle = '0x420000000000000000000000000000000000000F' +const L2_SECONDARYFEETOKEN_ADDRESS = '0x4200000000000000000000000000000000000023' + +const ADDRESS_CONFIG = { + [ NETWORK_TYPE.MAINNET ]: { + [ NETWORK.ETHEREUM ]: { + ...addresses_Mainnet, + ...layerZeroMainnet.BOBA_Bridges.Mainnet, + ...layerZeroMainnet.Layer_Zero_Protocol.Mainnet, + layerZeroTargetChainID: layerZeroMainnet.Layer_Zero_Protocol.Mainnet.Layer_Zero_ChainId, + }, + [ NETWORK.AVAX ]: { + ...addresses_BobaAvax, + ...layerZeroMainnet.BOBA_Bridges.Avalanche, + ...layerZeroMainnet.Layer_Zero_Protocol.Avalanche, + layerZeroTargetChainID: layerZeroMainnet.Layer_Zero_Protocol.Mainnet.Layer_Zero_ChainId, + }, + [ NETWORK.MOONBEAM ]: { + ...addresses_BobaBeam, + ...layerZeroMainnet.BOBA_Bridges.Moonbeam, + ...layerZeroMainnet.Layer_Zero_Protocol.Moonbeam, + layerZeroTargetChainID: layerZeroMainnet.Layer_Zero_Protocol.Mainnet.Layer_Zero_ChainId, + }, + [ NETWORK.BNB ]: { + ...addresses_BobaBnb, + ...layerZeroMainnet.BOBA_Bridges.BNB, + ...layerZeroMainnet.Layer_Zero_Protocol.BNB, + layerZeroTargetChainID: layerZeroMainnet.Layer_Zero_Protocol.Mainnet.Layer_Zero_ChainId, + }, + [ NETWORK.FANTOM ]: addresses_BobaOpera, + }, + [ NETWORK_TYPE.TESTNET ]: { + [ NETWORK.ETHEREUM ]: { + ...addresses_Goerli, + ...layerZeroTestnet.BOBA_Bridges.Testnet, + ...layerZeroTestnet.Layer_Zero_Protocol.Testnet, + layerZeroTargetChainID: layerZeroTestnet.Layer_Zero_Protocol.Testnet.Layer_Zero_ChainId, + }, + [ NETWORK.AVAX ]: { + ...addresses_BobaFuji, + ...layerZeroTestnet.BOBA_Bridges.Avalanche, + ...layerZeroTestnet.Layer_Zero_Protocol.Avalanche, + layerZeroTargetChainID: layerZeroTestnet.Layer_Zero_Protocol.Avalanche.Layer_Zero_ChainId, + }, + [ NETWORK.FANTOM ]: { + ...addresses_BobaOperaTestnet, + ...layerZeroTestnet.BOBA_Bridges.Fantom, + ...layerZeroTestnet.Layer_Zero_Protocol.Fantom, + layerZeroTargetChainID: layerZeroTestnet.Layer_Zero_Protocol.Fantom.Layer_Zero_ChainId, + }, + [ NETWORK.BNB ]: { + ...addresses_BobaBnbTestnet, + ...layerZeroTestnet.BOBA_Bridges.BNB, + ...layerZeroTestnet.Layer_Zero_Protocol.BNB, + layerZeroTargetChainID: layerZeroTestnet.Layer_Zero_Protocol.Fantom.Layer_Zero_ChainId, + }, + [ NETWORK.MOONBEAM ]: addresses_BobaBase, + } +} + +const SUPPORTED_ASSETS = { + [ NETWORK_TYPE.MAINNET ]: { + [ NETWORK.ETHEREUM ]: { + tokens: [ + 'USDT', 'DAI', 'USDC', 'WBTC', 'REP', 'BAT', 'ZRX', 'SUSHI', + 'LINK', 'UNI', 'BOBA', 'xBOBA', 'OMG', 'FRAX', 'FXS', 'DODO', + 'UST', 'BUSD', 'BNB', 'FTM', 'MATIC', 'UMA', 'DOM', 'OLO', + 'WAGMIv0', 'WAGMIv1', 'WAGMIv2', 'WAGMIv2-Oolong', 'WAGMIv3', 'WAGMIv3-Oolong', + 'CGT' + ], + tokenAddresses: { + WAGMIv0: { + 'L1': 'WAGMIv0', + 'L2': '0x8493C4d9Cd1a79be0523791E3331c78Abb3f9672' + }, + WAGMIv1: { + 'L1': 'WAGMIv1', + 'L2': '0xCe055Ea4f29fFB8bf35E852522B96aB67Cbe8197' + }, + WAGMIv2: { + 'L1': 'WAGMIv2', + 'L2': '0x76B5908ecd0ae3DB23011ae96b7C1f803D63136c' + }, + 'WAGMIv2-Oolong': { + 'L1': 'WAGMIv2-Oolong', + 'L2': '0x49a3e4a1284829160f95eE785a1A5FfE2DD5Eb1D' + }, + 'WAGMIv3': { + 'L1': 'WAGMIv3', + 'L2': '0xC6158B1989f89977bcc3150fC1F2eB2260F6cabE' + }, + 'WAGMIv3-Oolong': { + 'L1': 'WAGMIv3-Oolong', + 'L2': '0x70bf3c5B5d80C4Fece8Bde0fCe7ef38B688463d4' + }, + OLO: { + 'L1': 'OLO', + 'L2': '0x5008F837883EA9a07271a1b5eB0658404F5a9610' + }, + CGT: { + 'L1': '0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a', + 'L2': '0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a' + } + }, + altL1Chains: [ 'Moonbeam', 'BNB', 'Fantom', 'Avalanche' ] + }, + [ NETWORK.AVAX ]: { + tokenAddresses: { + 'EVO': { 'L1': '0x42006Ab57701251B580bDFc24778C43c9ff589A1', 'L2': '0xc8849f32138de93F6097199C5721a9EfD91ceE01' } + }, + tokens: [ 'BOBA', 'AVAX', 'EVO', 'USDT.e', 'USDt', 'USDC.e', 'BUSD.e', 'BUSD', 'DAI.e' ], + altL1Chains: [ 'Avalanche' ] + }, + [ NETWORK.MOONBEAM ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'GLMR' ], + altL1Chains: [ 'Moonbeam' ] + }, + [ NETWORK.BNB ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'BNB', 'BUSD', 'USDC', 'USDT', 'SUSHI' ], + altL1Chains: [ 'BNB' ] + }, + [ NETWORK.FANTOM ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'FTM', 'USDC', 'DAI' ], + altL1Chains: [ 'Bobaopera Mainnet' ] + }, + }, + [ NETWORK_TYPE.TESTNET ]: { + [ NETWORK.ETHEREUM ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'USDC', 'OMG', 'xBOBA' ], + altL1Chains: [ 'BNB', 'Fantom', 'Avalanche' ] + }, + [ NETWORK.AVAX ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'AVAX' ], + altL1Chains: [ 'Avalanche' ] + }, + [ NETWORK.MOONBEAM ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'GLMR' ], + altL1Chains: [ 'Moonbase' ] + }, + [ NETWORK.BNB ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'BNB', 'MMT' ], + altL1Chains: [ 'BNB' ] + }, + [ NETWORK.FANTOM ]: { + tokenAddresses: {}, + tokens: [ 'BOBA', 'FTM' ], + altL1Chains: [ 'Fantom' ] + }, + } +} + +class AppService { + + + + /** + * @fetchAddresses + * + * NOTE: + * Pre Deployeed contracts add address manually + * + * - L2StandardBridgeAddress + * - L2MessengerAddress + * - L2_ETH_Address + * - L1_ETH_Address + * + */ + + + fetchAddresses({ + networkType, + network + }) { + let addresses = ADDRESS_CONFIG[ networkType ][ network ] || {}; + + return { + ...addresses, + L1LPAddress: addresses.Proxy__L1LiquidityPool, + L2LPAddress: addresses.Proxy__L2LiquidityPool, + L2StandardBridgeAddress, + L2MessengerAddress, + L2_ETH_Address: L2_BOBA_Address, + L2_BOBA_Address, + L1_ETH_Address + }; + + } + + /** + * @fetchSupportedTokens + * - get the supported tokens base on network and network type. + * + * will return {supported tokens and token address} + * + */ + + fetchSupportedAssets({ + networkType, + network + }) { + return SUPPORTED_ASSETS[ networkType ][ network ] || {}; + } + + /** + * @setupInitState + * setup initial state of token reducer + * + */ + + setupInitState({ + l1Token, + l1TokenName + }) { + + store.dispatch({ + type: 'TOKEN/GET/SUCCESS', + payload: { + currency: L1_ETH_Address, + addressL1: L1_ETH_Address, + addressL2: L2_SECONDARYFEETOKEN_ADDRESS, + symbolL1: l1Token, + symbolL2: l1Token, + decimals: 18, + name: l1TokenName, + redalert: false, + } + }); + } + +}; + +const appService = new AppService(); + +export default appService; diff --git a/packages/boba/gateway/src/services/errorService.js b/packages/boba/gateway/src/services/error.service.js similarity index 100% rename from packages/boba/gateway/src/services/errorService.js rename to packages/boba/gateway/src/services/error.service.js diff --git a/packages/boba/gateway/src/services/faucet.service.js b/packages/boba/gateway/src/services/faucet.service.js new file mode 100644 index 0000000000..09a3c0ac05 --- /dev/null +++ b/packages/boba/gateway/src/services/faucet.service.js @@ -0,0 +1,81 @@ +import networkService from "./networkService"; +import AuthenticatedFaucetJson from "../deployment/contracts/AuthenticatedFaucet.json" +import { ethers } from "ethers"; +import metaTransactionAxiosInstance from "api/metaTransactionAxios"; + +class FaucetService { + + /** + * @getTestnetETHAuthenticatedMetaTransaction + * + * @dev Only works on testnet, but can be freely called on production app + * */ + async getTestnetETHAuthenticatedMetaTransaction(tweetId) { + + const Boba_AuthenticatedFaucet = new ethers.Contract( + networkService.addresses.AuthenticatedFaucet, + AuthenticatedFaucetJson.abi, + networkService.L2Provider, + ) + + const nonce = parseInt( + await Boba_AuthenticatedFaucet.getNonce(networkService.account), + 10 + ) + + const signer = networkService.provider.getSigner(networkService.account) + const hashedMsg = ethers.utils.solidityKeccak256( + ['address', 'uint'], + [networkService.account, nonce] + ) + const messageHashBin = ethers.utils.arrayify(hashedMsg) + const signature = await signer.signMessage(messageHashBin) + + try { + const response = await metaTransactionAxiosInstance( + networkService.networkConfig + ).post('/send.getTestnetETH', { hashedMsg, signature, tweetId, walletAddress: networkService.account }) + console.log(["metaTransactionAxiosInstance res",response]) + } catch (error) { + let errorMsg = error?.response?.data?.error?.error?.body + if (errorMsg) { + errorMsg = JSON.stringify(errorMsg)?.match(/execution reverted:\s(.+)\\"/) + errorMsg = errorMsg ? errorMsg[1]?.trim() : null; + } + console.log(`MetaTx error for getTestnetETH: ${errorMsg}`) + if (errorMsg?.includes('Invalid request')) { + errorMsg = errorMsg.match(/Invalid request:(.+)/) + if (errorMsg) { + const errorMap = [ + 'Twitter API error - Probably limits hit.', + 'Twitter account needs to exist at least 48 hours.', + 'Invalid Tweet, be sure to tweet the Boba Bubble provided above.', + 'Your Twitter account needs more than 5 followers.', + 'You need to have tweeted more than 2 times.', + ] + try { + errorMsg = errorMap[parseInt(errorMsg[1]) - 1] + } catch(err) { + console.error(err) + errorMsg = 'Unexpected Twitter error.' + } + } else { + errorMsg = 'Not expected Turing error.' + } + } else { + const errorMap = { + 'Cooldown': 'Cooldown: You need to wait 24h to claim again with this Twitter account.', + 'No testnet funds': 'Faucet drained: Please reach out to us.', + 'Rate limit reached': 'Throttling: Too many requests. Throttling to not hit Twitter rate limits.', + } + errorMsg = errorMap[errorMsg]; + } + return errorMsg ?? 'Limits reached or Twitter constraints not met.' + } + } + +} + +const faucetService = new FaucetService(); + +export default faucetService; diff --git a/packages/boba/gateway/src/services/gas.service.js b/packages/boba/gateway/src/services/gas.service.js new file mode 100644 index 0000000000..27b1418877 --- /dev/null +++ b/packages/boba/gateway/src/services/gas.service.js @@ -0,0 +1,39 @@ + + +import { logAmount } from "util/amountConvert"; +import networkService from "./networkService"; + + +class GasService { + + /** + * @getGas + */ + + async getGas() { + try { + // get gas price + const gasPrice1 = await networkService.L1Provider.getGasPrice() + const gasPrice2 = await networkService.L2Provider.getGasPrice() + // get block count + const block1 = await networkService.L1Provider.getBlockNumber() + const block2 = await networkService.L2Provider.getBlockNumber() + + const gasData = { + gasL1: Number(logAmount(gasPrice1.toString(),9)).toFixed(0), + gasL2: Number(logAmount(gasPrice2.toString(),9)).toFixed(0), + blockL1: Number(block1), + blockL2: Number(block2), + } + return gasData + } catch (error) { + console.log("GS: getGas error:",error) + return error + } + } + +} + +const gasService = new GasService(); + +export default gasService; diff --git a/packages/boba/gateway/src/services/graphQLService.js b/packages/boba/gateway/src/services/graphql.service.js similarity index 83% rename from packages/boba/gateway/src/services/graphQLService.js rename to packages/boba/gateway/src/services/graphql.service.js index bba8990b7b..602bb05e6c 100644 --- a/packages/boba/gateway/src/services/graphQLService.js +++ b/packages/boba/gateway/src/services/graphql.service.js @@ -1,14 +1,14 @@ import { ApolloClient, gql, HttpLink, InMemoryCache } from '@apollo/client'; import fetch from 'cross-fetch'; -import { APP_CHAIN } from 'util/constant' +import { NETWORK_TYPE } from 'util/network/network.util'; +import networkService from './networkService'; class GraphQLService { getBridgeEndpoint = () => { - if (APP_CHAIN === 'mainnet') { + + if (networkService.networkType === NETWORK_TYPE.MAINNET) { return `https://api.thegraph.com/subgraphs/name/bobanetwork/boba-l2-subgraph` - } else if (APP_CHAIN === 'goerli') { - return `https://graph.goerli.boba.network/subgraphs/name/boba/Bridges` } else { return '' } @@ -31,6 +31,13 @@ class GraphQLService { */ + if (NETWORK_TYPE.TESTNET === networkService.networkType) { + // As there is no subgraph node for goerli L2 disable it. + return { + data:{governorProposalCreateds: []} + } + } + const client = new ApolloClient({ uri: this.getBridgeEndpoint(), link: new HttpLink({ @@ -74,6 +81,12 @@ class GraphQLService { } */ + if (NETWORK_TYPE.TESTNET === networkService.networkType) { + return { + data: { turingMonstersTransferEvents: [] } + } + } + const client = new ApolloClient({ uri: this.getBridgeEndpoint(), link: new HttpLink({ diff --git a/packages/boba/gateway/src/services/networkService.js b/packages/boba/gateway/src/services/networkService.js index dbfec1b87a..a91102777a 100644 --- a/packages/boba/gateway/src/services/networkService.js +++ b/packages/boba/gateway/src/services/networkService.js @@ -41,12 +41,11 @@ import { import { updateSignatureStatus_exitLP, updateSignatureStatus_exitTRAD, - updateSignatureStatus_depositLP, - updateSignatureStatus_depositTRAD + updateSignatureStatus_depositLP } from 'actions/signAction' // Base contracts -import L1StandardBridgeJson from '@eth-optimism/contracts/artifacts/contracts/L1/messaging/L1StandardBridge.sol/L1StandardBridge.json' +// import L1StandardBridgeJson from '@eth-optimism/contracts/artifacts/contracts/L1/messaging/L1StandardBridge.sol/L1StandardBridge.json' import L2StandardBridgeJson from '@eth-optimism/contracts/artifacts/contracts/L2/messaging/L2StandardBridge.sol/L2StandardBridge.json' import L2ERC20Json from '@eth-optimism/contracts/artifacts/contracts/standards/L2StandardERC20.sol/L2StandardERC20.json' import OVM_GasPriceOracleJson from '@eth-optimism/contracts/artifacts/contracts/L2/predeploys/OVM_GasPriceOracle.sol/OVM_GasPriceOracle.json' @@ -64,10 +63,8 @@ import L2BillingContractJson from "@boba/contracts/artifacts/contracts/L2Billing //special one-off locations import L1ERC20Json from '../deployment/contracts/L1ERC20.json' -import OMGJson from '../deployment/contracts/OMG.json' import TuringMonsterJson from "../deployment/contracts/NFTMonsterV2.json" import AuthenticatedFaucetJson from "../deployment/contracts/AuthenticatedFaucet.json" -import Boba_GasPriceOracleJson from "../deployment/contracts/Boba_GasPriceOracle.json" //WAGMI ABIs import WAGMIv0Json from "../deployment/contracts/WAGMIv0.json" @@ -84,64 +81,32 @@ import L2StandardERC20Json from "../deployment/contracts/crosschain/L2StandardER import LZEndpointMockJson from "../deployment/contracts/crosschain/LZEndpointMock.json" import { getNftImageUrl } from 'util/nftImage' -import { getNetwork } from 'util/masterConfig' import omgxWatcherAxiosInstance from 'api/omgxWatcherAxios' import coinGeckoAxiosInstance from 'api/coinGeckoAxios' -import verifierWatcherAxiosInstance from 'api/verifierWatcherAxios' import metaTransactionAxiosInstance from 'api/metaTransactionAxios' import { sortRawTokens } from 'util/common' -import GraphQLService from "./graphQLService" - -import addresses_Goerli from "@boba/register/addresses/addressesGoerli_0x6FF9c8FF8F0B6a0763a3030540c21aFC721A9148" -import addresses_Mainnet from "@boba/register/addresses/addressesMainnet_0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089" - -import layerZeroTestnet from "@boba/register/addresses/layerZeroTestnet" -import layerZeroMainnet from "@boba/register/addresses/layerZeroMainnet" +import GraphQLService from "./graphql.service" import tokenInfo from "@boba/register/addresses/tokenInfo" import { bobaBridges } from 'util/bobaBridges' -import { APP_CHAIN, SPEED_CHECK } from 'util/constant' +import { MIN_NATIVE_L1_BALANCE, SPEED_CHECK } from 'util/constant' import { getPoolDetail } from 'util/poolDetails' +import { pingRpcUrl, getNetworkDetail, NETWORK, NETWORK_TYPE } from 'util/network/network.util' +import appService from './app.service' +import BobaGasPriceOracleABI from './abi/BobaGasPriceOracle.abi' +import L1StandardBridgeABI from './abi/L1StandardBridge.abi' const ERROR_ADDRESS = '0x0000000000000000000000000000000000000000' const L1_ETH_Address = '0x0000000000000000000000000000000000000000' const L2_ETH_Address = '0x4200000000000000000000000000000000000006' -const L2MessengerAddress = '0x4200000000000000000000000000000000000007' -const L2StandardBridgeAddress = '0x4200000000000000000000000000000000000010' +// const L2MessengerAddress = '0x4200000000000000000000000000000000000007' +// const L2StandardBridgeAddress = '0x4200000000000000000000000000000000000010' const L2GasOracle = '0x420000000000000000000000000000000000000F' -let supportedAltL1Chains = [] - -let allAddresses = {} -let l0AllProtocols = {} -// preload allAddresses -if (APP_CHAIN === 'goerli') { - const bobaBridges = layerZeroTestnet.BOBA_Bridges.Testnet; - const l0Protocols = layerZeroTestnet.Layer_Zero_Protocol.Testnet; - l0AllProtocols = layerZeroTestnet.Layer_Zero_Protocol; - allAddresses = { - ...addresses_Goerli, - L1LPAddress: addresses_Goerli.Proxy__L1LiquidityPool, - L2LPAddress: addresses_Goerli.Proxy__L2LiquidityPool, - ...bobaBridges, - ...l0Protocols - } - supportedAltL1Chains = ['BNB', 'Fantom', 'Avalanche'] -} else if (APP_CHAIN === 'mainnet') { - const bobaBridges = layerZeroMainnet.BOBA_Bridges.Mainnet; - const l0Protocols = layerZeroMainnet.Layer_Zero_Protocol.Mainnet; - l0AllProtocols = layerZeroMainnet.Layer_Zero_Protocol; - allAddresses = { - ...addresses_Mainnet, - L1LPAddress: addresses_Mainnet.Proxy__L1LiquidityPool, - L2LPAddress: addresses_Mainnet.Proxy__L2LiquidityPool, - ...bobaBridges, - ...l0Protocols - } - supportedAltL1Chains = ['Moonbeam','BNB', 'Fantom', 'Avalanche'] -} +const L2_SECONDARYFEETOKEN_ADDRESS = '0x4200000000000000000000000000000000000023' + let allTokens = {} function handleChangeChainOnce(chainID_hex_string) { @@ -167,8 +132,8 @@ class NetworkService { // L1 or L2 this.L1orL2 = null this.networkGateway = null - this.L1ProviderBASE = null - this.L2ProviderBASE = null + this.networkType = null + // Watcher this.watcher = null @@ -190,7 +155,6 @@ class NetworkService { this.AtomicSwapContract = null this.tokenAddresses = null - this.addresses = null // chain ID this.chainID = null @@ -221,12 +185,18 @@ class NetworkService { // support token this.supportedTokens = [] + this.supportedTokenAddresses = {} // support alt l1 tokens - this.supportedAltL1Chains = supportedAltL1Chains + this.supportedAltL1Chains = [] // token info this.tokenInfo = {} + + // newly added properties to network services. + this.addresses = {} + this.network = null; + this.networkConfig = null } bindProviderListeners() { @@ -248,40 +218,37 @@ class NetworkService { }) } - async fetchVerifierStatus() { - const response = await verifierWatcherAxiosInstance( - this.networkGateway - ).post('/', { jsonrpc: "2.0", method: "status", id: 1 }) - - if (response.status === 200) { - const status = response.data.result - return status - } else { - console.log("Bad verifier response") - return false - } - } async getBobaFeeChoice() { + const bobaFeeContract = new ethers.Contract( - allAddresses.Boba_GasPriceOracle, - Boba_GasPriceOracleJson.abi, + this.addresses.Boba_GasPriceOracle, + BobaGasPriceOracleABI, this.L2Provider ) try { - let priceRatio = await bobaFeeContract.priceRatio() - let feeChoice = await bobaFeeContract.bobaFeeTokenUsers(this.account) + let feeChoice; + if (this.networkGateway === NETWORK.ETHEREUM) { + feeChoice = await bobaFeeContract.bobaFeeTokenUsers(this.account) + } else { + // this returns weather the secondary token getting use as tokenfee + feeChoice = await bobaFeeContract.secondaryFeeTokenUsers(this.account) + // if it's false which means boba is getting used as tokenfee which is default value. + feeChoice = !feeChoice; + + } + console.log( + 'Fee used as boba', feeChoice + ) const bobaFee = { priceRatio: priceRatio.toString(), feeChoice } - await addBobaFee( bobaFee ) - return bobaFee } catch (error) { @@ -289,6 +256,26 @@ class NetworkService { console.log(error) return error } + } + + async estimateMinL1NativeTokenForFee() { + if(this.L1orL2 !== 'L2' ) return 0; + + if (this.networkGateway === NETWORK.ETHEREUM) { + // for ethereum l1 fee is always const to 0.002. + return MIN_NATIVE_L1_BALANCE + } else { + // for alt l1 this fee can change + const bobaFeeContract = new ethers.Contract( + this.addresses.Boba_GasPriceOracle, + BobaGasPriceOracleABI, + this.provider.getSigner() + ) + + const minTokenForFee = await bobaFeeContract.secondaryFeeTokenMinimum(); + + return logAmount(minTokenForFee.toString(), 18) + } } @@ -297,8 +284,8 @@ class NetworkService { if( this.L1orL2 !== 'L2' ) return const bobaFeeContract = new ethers.Contract( - allAddresses.Boba_GasPriceOracle, - Boba_GasPriceOracleJson.abi, + this.addresses.Boba_GasPriceOracle, + BobaGasPriceOracleABI, this.provider.getSigner() ) @@ -313,6 +300,9 @@ class NetworkService { } else if (targetFee === 'ETH') { tx = await bobaFeeContract.useETHAsFeeToken() await tx.wait() + } else if (targetFee === this.L1NativeTokenSymbol) { + tx = await bobaFeeContract.useSecondaryFeeTokenAsFeeToken() + await tx.wait() } await this.getBobaFeeChoice() @@ -341,15 +331,23 @@ class NetworkService { ] const owner = this.account - const spender = allAddresses.Boba_GasPriceOracle + const spender = this.addresses.Proxy__Boba_GasPriceOracle const Boba_GasPriceOracle = new ethers.Contract( - allAddresses.Boba_GasPriceOracle, - Boba_GasPriceOracleJson.abi, + this.addresses.Proxy__Boba_GasPriceOracle, + BobaGasPriceOracleABI, this.provider.getSigner() ) - let value = (await Boba_GasPriceOracle.getBOBAForSwap()).toString() + let rawValue; + if (this.networkGateway === NETWORK.ETHEREUM) { + rawValue = await Boba_GasPriceOracle.getBOBAForSwap(); + } else { + rawValue = await Boba_GasPriceOracle.getSecondaryFeeTokenForSwap(); + } + + let value = (rawValue).toString() + const nonce = (await this.BobaContract.nonces(this.account)).toNumber() const deadline = Math.floor(Date.now() / 1000) + 300 const verifyingContract = this.BobaContract.address @@ -368,108 +366,37 @@ class NetworkService { let signature try { - signature = await this.provider.send('eth_signTypedData_v4', [this.account, JSON.stringify(data)]) + signature = await this.provider.send('eth_signTypedData_v4', [ this.account, JSON.stringify(data) ]) } catch (error) { - console.log(error) return error } try { + // change url if network is ethereum + const swapUrl = this.networkGateway === NETWORK.ETHEREUM ? '/send.swapBOBAForETH' : '/send.swapSecondaryFeeToken' const response = await metaTransactionAxiosInstance( - this.networkGateway - ).post('/send.swapBOBAForETH', { owner, spender, value, deadline, signature, data }) - console.log("response",response) + this.networkConfig + ).post(swapUrl, { owner, spender, value, deadline, signature, data }) + console.log(['meta tx fee res', response]) await this.getBobaFeeChoice() } catch (error) { - console.log(error) - // sigh let errorData = error.response.data.error if(errorData.hasOwnProperty('error')) { errorData = errorData.error.error.body } - console.log("returning:",error) return errorData } } - /** @dev Only works on testnet, but can be freely called on production app */ - async getTestnetETHAuthenticatedMetaTransaction(tweetId) { - - console.log("triggering getTestnetETH") - - const Boba_AuthenticatedFaucet = new ethers.Contract( - addresses_Goerli.AuthenticatedFaucet, - AuthenticatedFaucetJson.abi, - this.L2Provider, - ) - - const nonce = parseInt( - await Boba_AuthenticatedFaucet.getNonce(this.account), - 10 - ) - - const signer = this.provider.getSigner(this.account) - const hashedMsg = ethers.utils.solidityKeccak256( - ['address', 'uint'], - [this.account, nonce] - ) - const messageHashBin = ethers.utils.arrayify(hashedMsg) - const signature = await signer.signMessage(messageHashBin) - - try { - const response = await metaTransactionAxiosInstance( - this.networkGateway - ).post('/send.getTestnetETH', { hashedMsg, signature, tweetId, walletAddress: this.account }) - console.log("response",response) - } catch (error) { - let errorMsg = error?.response?.data?.error?.error?.body - if (errorMsg) { - errorMsg = JSON.stringify(errorMsg)?.match(/execution reverted:\s(.+)\\"/) - errorMsg = errorMsg ? errorMsg[1]?.trim() : null; - } - console.log(`MetaTx error for getTestnetETH: ${errorMsg}`) - if (errorMsg?.includes('Invalid request')) { - errorMsg = errorMsg.match(/Invalid request:(.+)/) - if (errorMsg) { - const errorMap = [ - 'Twitter API error - Probably limits hit.', - 'Twitter account needs to exist at least 48 hours.', - 'Invalid Tweet, be sure to tweet the Boba Bubble provided above.', - 'Your Twitter account needs more than 5 followers.', - 'You need to have tweeted more than 2 times.', - ] - try { - errorMsg = errorMap[parseInt(errorMsg[1]) - 1] - } catch(err) { - console.error(err) - errorMsg = 'Unexpected Twitter error.' - } - } else { - errorMsg = 'Not expected Turing error.' - } - } else { - const errorMap = { - 'Cooldown': 'Cooldown: You need to wait 24h to claim again with this Twitter account.', - 'No testnet funds': 'Faucet drained: Please reach out to us.', - 'Rate limit reached': 'Throttling: Too many requests. Throttling to not hit Twitter rate limits.', - } - errorMsg = errorMap[errorMsg]; - } - return errorMsg ?? 'Limits reached or Twitter constraints not met.' - } - } - async getAddress(contractName, varToSet) { const address = await this.AddressManager.getAddress(contractName) if (address === ERROR_ADDRESS) { - console.log(contractName + ' ERROR: NOT IN ADDRESSMANAGER') return false } else { - allAddresses = { - ...allAddresses, + this.addresses = { + ...this.addresses, [varToSet]: address } - console.log(contractName +' pulled from AddressManager and set to:', address) return true } } @@ -477,72 +404,93 @@ class NetworkService { async getAddressCached(cache, contractName, varToSet) { const address = cache[contractName] if (typeof(address) === 'undefined') { - console.log(contractName + ' ERROR: NOT IN CACHE') return false } else { - allAddresses = { - ...allAddresses, + this.addresses = { + ...this.addresses, [varToSet]: address } - console.log(contractName +' pulled from address cache and set to:', address) return true } } getAllAddresses() { - return allAddresses + return this.addresses; } - async initializeBase( networkGateway ) { - - console.log('NS: initializeBase() for', networkGateway) + async initializeBase({ + networkGateway: network, + networkType + }) { - let addresses = null - this.networkGateway = networkGateway // e.g. mainnet | goerli | ... + this.network = network; //// refer this in other services and clean up iteratively. + this.networkGateway = network // e.g. mainnet | goerli | ... + this.networkType = networkType // e.g. mainnet | goerli | ... // defines the set of possible networks along with chainId for L1 and L2 - const nw = getNetwork() - const L1rpc = nw[networkGateway]['L1']['rpcUrl'] - const L2rpc = nw[networkGateway]['L2']['rpcUrl'] - - try { + const networkDetail = getNetworkDetail({ + network, + networkType + }) - //fire up the base providers - const Web3 = require("web3") + this.networkConfig = networkDetail; - this.L1ProviderBASE = new Web3(new Web3.providers.HttpProvider(L1rpc)) - this.L2ProviderBASE = new Web3(new Web3.providers.HttpProvider(L2rpc)) + try { - //this.L1ProviderBASE.eth.handleRevert = true - //this.L2ProviderBASE.eth.handleRevert = true + if (NETWORK[network]) { + this.payloadForL1SecurityFee = networkDetail.payloadForL1SecurityFee + this.payloadForFastDepositBatchCost = networkDetail.payloadForFastDepositBatchCost + this.gasEstimateAccount = networkDetail.gasEstimateAccount + } - if (networkGateway === 'mainnet' || networkGateway === 'goerli') { - this.payloadForL1SecurityFee = nw[networkGateway].payloadForL1SecurityFee - this.payloadForFastDepositBatchCost = nw[networkGateway].payloadForFastDepositBatchCost - this.gasEstimateAccount = nw[networkGateway].gasEstimateAccount - console.log('gasEstimateAccount:', this.gasEstimateAccount) + let activeL1RpcURL = networkDetail['L1']['rpcUrl'][0] + for (const rpcURL of networkDetail['L1']['rpcUrl']) { + if (await pingRpcUrl(rpcURL)) { + activeL1RpcURL = rpcURL + break + } } this.L1Provider = new ethers.providers.StaticJsonRpcProvider( - nw[networkGateway]['L1']['rpcUrl'] + activeL1RpcURL ) this.L2Provider = new ethers.providers.StaticJsonRpcProvider( - nw[networkGateway]['L2']['rpcUrl'] + networkDetail['L2']['rpcUrl'] ) + this.L1NativeTokenSymbol = networkDetail['L1']['symbol'] + this.L1NativeTokenName = networkDetail['L1']['tokenName'] || this.L1NativeTokenSymbol + + appService.setupInitState({ + l1Token: this.L1NativeTokenSymbol, + l1TokenName: this.L1NativeTokenName + }) + + // get the tokens based on l1ChainId const chainId = (await this.L1Provider.getNetwork()).chainId this.tokenInfo = tokenInfo[chainId] - if (networkGateway === 'goerli') { - addresses = addresses_Goerli - } else if (networkGateway === 'mainnet') { - addresses = addresses_Mainnet + // fetch supported tokens, addresses, assets for network selected. + const tokenAsset = appService.fetchSupportedAssets({ + network, + networkType + }) + + this.supportedTokens = tokenAsset.tokens; + this.supportedTokenAddresses = tokenAsset.tokenAddresses; + this.supportedAltL1Chains = tokenAsset.altL1Chains; + + let addresses = {}; + // setting up all address; + if (!!NETWORK[ network ]) { + addresses = appService.fetchAddresses({ + network, + networkType + }); } - // else if (networkGateway === 'local') { - // //addresses = addresses_Local - // console.log('Goerli Addresses:', addresses) - // } + + this.addresses = addresses // this.AddressManagerAddress = nw[networkGateway].addressManager // console.log("AddressManager address:",this.AddressManagerAddress) @@ -554,171 +502,75 @@ class NetworkService { // ) // //console.log("AddressManager Contract:",this.AddressManager) - if (!(await this.getAddressCached(addresses, 'Proxy__L1CrossDomainMessenger', 'L1MessengerAddress'))) return - if (!(await this.getAddressCached(addresses, 'Proxy__L1CrossDomainMessengerFast', 'L1FastMessengerAddress'))) return - if (!(await this.getAddressCached(addresses, 'Proxy__L1StandardBridge', 'L1StandardBridgeAddress'))) return - if (!(await this.getAddressCached(addresses, 'Proxy__BobaFixedSavings', 'BobaFixedSavings'))) return - if (!(await this.getAddressCached(addresses, 'Proxy__Boba_GasPriceOracle', 'Boba_GasPriceOracle'))) return - //if (!(await this.getAddressCached(addresses, 'DiscretionaryExitFee', 'DiscretionaryExitFee'))) return - - // not critical - this.getAddressCached(addresses, 'DiscretionaryExitFee', 'DiscretionaryExitFee') - console.log("DiscretionaryExitFee:",allAddresses.DiscretionaryExitFee) - - //L2CrossDomainMessenger is a predeploy, so add by hand.... - allAddresses = { - ...allAddresses, - 'L2MessengerAddress': L2MessengerAddress, - } - - //L2StandardBridgeAddress is a predeploy, so add by hand.... - allAddresses = { - ...allAddresses, - 'L2StandardBridgeAddress': L2StandardBridgeAddress, - } - - //L2MessengerAddress is a predeploy, so add by hand.... - allAddresses = { - ...allAddresses, - 'L2MessengerAddress': L2MessengerAddress + if (network === NETWORK.ETHEREUM) { + // check only if selected network is ETHEREUM + if (!(await this.getAddressCached(this.addresses, 'BobaMonsters', 'BobaMonsters'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__L1LiquidityPool', 'L1LPAddress'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__L2LiquidityPool', 'L2LPAddress'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__BobaFixedSavings', 'BobaFixedSavings'))) return } - //L2_ETH_Address is a predeploy, so add by hand.... - allAddresses = { - ...allAddresses, - 'L2_ETH_Address': L2_ETH_Address - } + if (!(await this.getAddressCached(this.addresses, 'Proxy__L1CrossDomainMessenger', 'L1MessengerAddress'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__L1CrossDomainMessengerFast', 'L1FastMessengerAddress'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__L1StandardBridge', 'L1StandardBridgeAddress'))) return + if (!(await this.getAddressCached(this.addresses, 'Proxy__Boba_GasPriceOracle', 'Boba_GasPriceOracle'))) return - //L1_ETH_Address is a predeploy, so add by hand.... - allAddresses = { - ...allAddresses, - 'L1_ETH_Address': L1_ETH_Address - } + // not critical + this.getAddressCached(this.addresses, 'DiscretionaryExitFee', 'DiscretionaryExitFee') this.L1StandardBridgeContract = new ethers.Contract( - allAddresses.L1StandardBridgeAddress, - L1StandardBridgeJson.abi, + this.addresses.L1StandardBridgeAddress, + L1StandardBridgeABI, this.L1Provider ) - this.supportedTokens = [ 'USDT', 'DAI', 'USDC', 'WBTC', - 'REP', 'BAT', 'ZRX', 'SUSHI', - 'LINK', 'UNI', 'BOBA', 'xBOBA', - 'OMG', 'FRAX', 'FXS', 'DODO', - 'UST', 'BUSD', 'BNB', 'FTM', - 'MATIC', 'UMA', 'DOM', 'OLO', - 'WAGMIv0', - 'WAGMIv1', - 'WAGMIv2', 'WAGMIv2-Oolong', - 'WAGMIv3', 'WAGMIv3-Oolong', - 'CGT' - ] - - //not all tokens are on Goerli - if ( networkGateway === 'goerli') { - this.supportedTokens = [ 'BOBA', 'USDC', 'OMG', 'xBOBA' ] - } - - await Promise.all(this.supportedTokens.map(async (key) => { + const tokenList = {} - const L2a = addresses['TK_L2'+key] + this.supportedTokens.forEach((key) => { + const L1a = this.addresses[ 'TK_L1' + key ] + const L2a = this.addresses[ 'TK_L2' + key ] - if(key === 'xBOBA') { + if (key === 'xBOBA') { if (L2a === ERROR_ADDRESS) { - console.log(key + ' ERROR: TOKEN NOT IN ADDRESSMANAGER') return false } else { - allTokens[key] = { + tokenList[ key ] = { 'L1': 'xBOBA', 'L2': L2a } } } - else if(key === 'WAGMIv0') { - allTokens[key] = { - 'L1': 'WAGMIv0', - 'L2': '0x8493C4d9Cd1a79be0523791E3331c78Abb3f9672' - } - } - else if(key === 'WAGMIv1') { - allTokens[key] = { - 'L1': 'WAGMIv1', - 'L2': '0xCe055Ea4f29fFB8bf35E852522B96aB67Cbe8197' - } - } - else if(key === 'WAGMIv2') { - allTokens[key] = { - 'L1': 'WAGMIv2', - 'L2': '0x76B5908ecd0ae3DB23011ae96b7C1f803D63136c' - } - } - else if(key === 'WAGMIv2-Oolong') { - allTokens[key] = { - 'L1': 'WAGMIv2-Oolong', - 'L2': '0x49a3e4a1284829160f95eE785a1A5FfE2DD5Eb1D' - } - } - else if(key === 'WAGMIv3') { - allTokens[key] = { - 'L1': 'WAGMIv3', - 'L2': '0xC6158B1989f89977bcc3150fC1F2eB2260F6cabE' - } - } - else if(key === 'WAGMIv3-Oolong') { - allTokens[key] = { - 'L1': 'WAGMIv3-Oolong', - 'L2': '0x70bf3c5B5d80C4Fece8Bde0fCe7ef38B688463d4' - } - } - else if(key === 'OLO') { - allTokens[key] = { - 'L1': 'OLO', - 'L2': '0x5008F837883EA9a07271a1b5eB0658404F5a9610' - } - } - else if(key === 'CGT') { - allTokens[key] = { - 'L1': '0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a', - 'L2': '0xf56b164efd3cfc02ba739b719b6526a6fa1ca32a' + + // NOTE: if not in address manager then refer it from token assets config. + if (typeof L1a === 'undefined' || typeof L2a === 'undefined') { + if (typeof this.supportedTokenAddresses[key] !== 'undefined') { + tokenList[key] = this.supportedTokenAddresses[key] } - } - else { - const L1a = addresses['TK_L1'+key] - if (L1a === ERROR_ADDRESS || L2a === ERROR_ADDRESS) { - console.log(key + ' ERROR: TOKEN NOT IN ADDRESSMANAGER') - return false - } else { - allTokens[key] = { - 'L1': L1a, - 'L2': L2a - } + return false + } else { + tokenList[key] = { + 'L1': L1a, + 'L2': L2a } } + }) - })) - - this.tokenAddresses = allTokens - - if (!(await this.getAddressCached(addresses, 'BobaMonsters', 'BobaMonsters'))) return - - if (!(await this.getAddressCached(addresses, 'Proxy__L1LiquidityPool', 'L1LPAddress'))) return - if (!(await this.getAddressCached(addresses, 'Proxy__L2LiquidityPool', 'L2LPAddress'))) return + this.tokenAddresses = tokenList + allTokens = tokenList; - if(allAddresses.L2StandardBridgeAddress !== null) { + if(this.addresses.L2StandardBridgeAddress !== null) { this.L2StandardBridgeContract = new ethers.Contract( - allAddresses.L2StandardBridgeAddress, + this.addresses.L2StandardBridgeAddress, L2StandardBridgeJson.abi, this.L2Provider ) } - console.log("L2StandardBridgeContract:", this.L2StandardBridgeContract.address) this.L2_ETH_Contract = new ethers.Contract( - allAddresses.L2_ETH_Address, + this.addresses.L2_ETH_Address, L2ERC20Json.abi, this.L2Provider ) - //console.log("L2_ETH_Contract:", this.L2_ETH_Contract.address) /*The test token*/ this.L1_TEST_Contract = new ethers.Contract( @@ -726,103 +578,82 @@ class NetworkService { L1ERC20Json.abi, this.L1Provider ) - //console.log('L1_TEST_Contract:', this.L1_TEST_Contract) this.L2_TEST_Contract = new ethers.Contract( allTokens.BOBA.L2, //this will get changed anyway when the contract is used L2ERC20Json.abi, this.L2Provider ) - //console.log('L2_TEST_Contract:', this.L2_TEST_Contract) /*The OMG token*/ //We need this seperately because OMG is not ERC20 compliant - this.L1_OMG_Contract = new ethers.Contract( + /* this.L1_OMG_Contract = new ethers.Contract( allTokens.OMG.L1, OMGJson, this.L1Provider - ) + ) */ //console.log('L1_OMG_Contract:', this.L1_OMG_Contract) // Liquidity pools - console.log('Setting up contract for L1LP at:',allAddresses.L1LPAddress) + this.L1LPContract = new ethers.Contract( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, L1LPJson.abi, this.L1Provider ) - - console.log('Setting up contract for L2LP at:',allAddresses.L2LPAddress) this.L2LPContract = new ethers.Contract( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, L2LPJson.abi, this.L2Provider ) - if(networkGateway === 'mainnet') { - this.watcher = new CrossChainMessenger({ - l1SignerOrProvider: this.L1Provider, - l2SignerOrProvider: this.L2Provider, - l1ChainId: 1, - fastRelayer: false, - }) - this.fastWatcher = new CrossChainMessenger({ - l1SignerOrProvider: this.L1Provider, - l2SignerOrProvider: this.L2Provider, - l1ChainId: 1, - fastRelayer: true, - }) - } else if (networkGateway === 'goerli') { - this.watcher = new CrossChainMessenger({ - l1SignerOrProvider: this.L1Provider, - l2SignerOrProvider: this.L2Provider, - l1ChainId: 5, - fastRelayer: false, - }) - this.fastWatcher = new CrossChainMessenger({ - l1SignerOrProvider: this.L1Provider, - l2SignerOrProvider: this.L2Provider, - l1ChainId: 5, - fastRelayer: true, - }) - } - else { - this.watcher = null - this.fastWatcher = null - } + this.watcher = new CrossChainMessenger({ + l1SignerOrProvider: this.L1Provider, + l2SignerOrProvider: this.L2Provider, + l1ChainId: chainId, + fastRelayer: false, + }) + this.fastWatcher = new CrossChainMessenger({ + l1SignerOrProvider: this.L1Provider, + l2SignerOrProvider: this.L2Provider, + l1ChainId: chainId, + fastRelayer: true, + }) this.BobaContract = new ethers.Contract( - allTokens.BOBA.L2, + L2_SECONDARYFEETOKEN_ADDRESS, Boba.abi, this.L2Provider ) - this.xBobaContract = new ethers.Contract( - allTokens.xBOBA.L2, - Boba.abi, - this.L2Provider - ) + if (NETWORK.ETHEREUM === network) { + this.xBobaContract = new ethers.Contract( + allTokens.xBOBA.L2, + Boba.abi, + this.L2Provider + ) - if (!(await this.getAddressCached(addresses, 'GovernorBravoDelegate', 'GovernorBravoDelegate'))) return - if (!(await this.getAddressCached(addresses, 'GovernorBravoDelegator', 'GovernorBravoDelegator'))) return + if (!(await this.getAddressCached(this.addresses, 'GovernorBravoDelegate', 'GovernorBravoDelegate'))) return + if (!(await this.getAddressCached(this.addresses, 'GovernorBravoDelegator', 'GovernorBravoDelegator'))) return - this.delegateContract = new ethers.Contract( - allAddresses.GovernorBravoDelegate, - GovernorBravoDelegate.abi, - this.L2Provider - ) + this.delegateContract = new ethers.Contract( + this.addresses.GovernorBravoDelegate, + GovernorBravoDelegate.abi, + this.L2Provider + ) - this.delegatorContract = new ethers.Contract( - allAddresses.GovernorBravoDelegator, - GovernorBravoDelegator.abi, - this.L2Provider - ) + this.delegatorContract = new ethers.Contract( + this.addresses.GovernorBravoDelegator, + GovernorBravoDelegator.abi, + this.L2Provider + ) - this.delegatorContractV2 = new ethers.Contract( - allAddresses.GovernorBravoDelegatorV2, - GovernorBravoDelegator.abi, - this.L2Provider - ) + this.delegatorContractV2 = new ethers.Contract( + this.addresses.GovernorBravoDelegatorV2, + GovernorBravoDelegator.abi, + this.L2Provider + ) + } this.gasOracleContract = new ethers.Contract( L2GasOracle, @@ -838,12 +669,14 @@ class NetworkService { } } - async initializeAccount( networkGateway ) { - - console.log('NS: initializeAccounts() for', networkGateway) + async initializeAccount({ networkGateway: network, networkType }) { try { + if (!window.ethereum) { + return 'nometamask' + } + // connect to the wallet await window.ethereum.request({method: 'eth_requestAccounts'}) this.provider = new ethers.providers.Web3Provider(window.ethereum) @@ -852,58 +685,35 @@ class NetworkService { const networkMM = await this.provider.getNetwork() this.chainID = networkMM.chainId this.networkName = networkMM.name - this.networkGateway = networkGateway - - console.log('NS: networkMM:', networkMM) - console.log('NS: networkGateway:', networkGateway) - console.log('NS: this.chainID from MM:', this.chainID) - console.log('NS: this.networkName from MM:', this.networkName) - console.log('NS: this.account from MM:', this.account) + this.networkGateway = network + this.networkType = networkType // defines the set of possible networks along with chainId for L1 and L2 - const nw = getNetwork() - const L1ChainId = nw[networkGateway]['L1']['chainId'] - const L2ChainId = nw[networkGateway]['L2']['chainId'] - - // there are numerous possible chains we could be on - // either local, goerli etc - // also, either L1 or L2 - - // at this point, we only know whether we want to be on local or goerli etc - if (networkGateway === 'local' && networkMM.chainId === L2ChainId) { - //ok, that's reasonable - //local deployment, L2 - this.L1orL2 = 'L2' - } else if (networkGateway === 'local' && networkMM.chainId === L1ChainId) { - //ok, that's reasonable - //local deployment, L1 - this.L1orL2 = 'L1' - } else if (networkGateway === 'goerli' && networkMM.chainId === L1ChainId) { - //ok, that's reasonable - //goerli, L1 - this.L1orL2 = 'L1' - } else if (networkGateway === 'goerli' && networkMM.chainId === L2ChainId) { - //ok, that's reasonable - //goerli, L2 - this.L1orL2 = 'L2' - } else if (networkGateway === 'mainnet' && networkMM.chainId === L1ChainId) { - //ok, that's reasonable - //mainnet, L2 - this.L1orL2 = 'L1' - } else if (networkGateway === 'mainnet' && networkMM.chainId === L2ChainId) { - //ok, that's reasonable - //mainnet, L2 - this.L1orL2 = 'L2' + const networkDetail = getNetworkDetail({ + network, + networkType + }) + + const L1ChainId = networkDetail['L1']['chainId'] + const L2ChainId = networkDetail['L2']['chainId'] + + // there are numerous possible chains we could be on also, either L1 or L2 + // at this point, we only know whether we want to be on which network etc + + if (!!NETWORK[ network ] && networkMM.chainId === L2ChainId) { + this.L1orL2 = 'L2'; + } else if(!!NETWORK[ network ] && networkMM.chainId === L1ChainId) { + this.L1orL2 = 'L1'; } else { - console.log("ERROR: networkGateway does not match actual network.chainId") this.bindProviderListeners() return 'wrongnetwork' } this.bindProviderListeners() // this should not do anything unless we changed chains - - await this.getBobaFeeChoice() + if (this.L1orL2 === 'L2') { + await this.getBobaFeeChoice() + } return this.L1orL2 // return the layer we are actually on @@ -913,172 +723,57 @@ class NetworkService { } } - async addL2Network() { - - console.log("MetaMask: Adding network to MetaMask") - - const nw = getNetwork() - const masterConfig = store.getState().setup.masterConfig - - const chainParam = { - chainId: '0x' + nw[masterConfig].L2.chainId.toString(16), - chainName: nw[masterConfig].L2.name, - rpcUrls: [nw[masterConfig].L2.rpcUrl], - blockExplorerUrls: [nw[masterConfig].L2.blockExplorer.slice(0, -1)], - } - console.log("MetaMask: Adding ", chainParam) - - // connect to the wallet - this.provider = new ethers.providers.Web3Provider(window.ethereum) - let res = await this.provider.send('wallet_addEthereumChain', [chainParam, this.account]) - - if( res === null ){ - console.log("MetaMask - Added new RPC") - } else { - console.log("MetaMask - Error adding new RPC: ", res) - } - - } + async switchChain(targetLayer) { + const networkDetail = getNetworkDetail({ + network: this.networkGateway, + networkType: this.networkType + }) - async switchChain( targetLayer ) { - - const nw = getNetwork() - const network = store.getState().setup.network - - let blockExplorerUrls = null - - //local does not have a blockexplorer - if( network !== 'local') { - blockExplorerUrls = [nw[network].L2.blockExplorer.slice(0, -1)] - } - - //the chainParams are only needed for the L2s - const chainParam = { - chainId: '0x' + nw[network].L2.chainId.toString(16), - chainName: nw[network].L2.name, - rpcUrls: [nw[network].L2.rpcUrl], - nativeCurrency: { - name: 'Ethereum', - symbol: 'ETH', - decimals: 18, - }, - blockExplorerUrls - } + const targetIDHex = networkDetail[targetLayer].chainIdHex - const targetIDHex = nw[network][targetLayer].chainIdHex + try { - this.provider = new ethers.providers.Web3Provider(window.ethereum) + this.provider = new ethers.providers.Web3Provider(window.ethereum) - try { await this.provider.send('wallet_switchEthereumChain', [{ chainId: targetIDHex }]) - window.ethereum.on('chainChanged', handleChangeChainOnce) + return true } catch (error) { // 4902 = the chain has not been added to MetaMask. // So, lets add it if (error.code === 4902) { + const rpcURL = targetLayer === 'L1' ? this.L1Provider.connection.url : networkDetail[targetLayer].rpcURL try { + //the chainParams are only needed for the L2s + const chainParam = { + chainId: '0x' + networkDetail[targetLayer].chainId.toString(16), + chainName: networkDetail[targetLayer].name, + rpcUrls: rpcURL, + nativeCurrency: { + name: networkDetail[targetLayer].tokenName, + symbol: networkDetail[targetLayer].symbol, + decimals: 18, + }, + blockExplorerUrls: [networkDetail[targetLayer]?.blockExplorer?.slice(0, -1)] + } + await this.provider.send('wallet_addEthereumChain', [chainParam, this.account]) window.ethereum.on('chainChanged', handleChangeChainOnce) return true } catch (addError) { console.log("MetaMask - Error adding new RPC: ", addError) - return addError + throw new Error(addError.code) } } else { //some other error code console.log("MetaMask - Switch Error: ", error.code) - return error + throw new Error(error.code) } } } - async getTransactions() { - - // NOT SUPPORTED on LOCAL - if (this.networkGateway === 'local') return - if (this.account === null) return - - let txL1pending = [] - let txL2 = [] - let txL0 = [] - - const responseL2 = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('get.l2.transactions', { - address: this.account, - fromRange: 0, - toRange: 1000, - }) - - if (responseL2.status === 201) { - txL2 = responseL2.data.map(v => ({ ...v, chain: 'L2' })) - } - - const responseL0 = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('get.layerzero.transactions', { - address: this.account, - fromRange: 0, - toRange: 1000, - }) - - if (responseL0.status === 201) { - txL0 = responseL0.data.map((v) => ({ - ...v, - hash: v.tx_hash, - blockNumber: parseInt(v.block_number), - timeStamp: parseInt(v.timestamp), //fix bug - sometimes this is string, sometimes an integer - chain: 'L0', - altL1: true, - })) - } - - const responseL1pending = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('get.l1.transactions', { - address: this.account, - fromRange: 0, - toRange: 1000, - }) - - if (responseL1pending.status === 201) { - //add the chain: 'L1pending' field - txL1pending = responseL1pending.data.map(v => ({ ...v, chain: 'L1pending' })) - const annotated = [ - ...txL2, - ...txL0, - ...txL1pending //the new data product - ] - return annotated - } - - } - - async getExits() { - // NOT SUPPORTED on LOCAL - if (this.networkGateway === 'local') return - - const response = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('get.l2.transactions', { - address: this.account, - fromRange: 0, - toRange: 1000, - }) - - if (response.status === 201) { - const transactions = response.data - const filteredTransactions = transactions.filter( - (i) => i.exitL2 && i.crossDomainMessage - ) - return { exited: filteredTransactions } - } - - } - async getSevens() { console.log("getSevens()") @@ -1087,7 +782,7 @@ class NetworkService { if (this.networkGateway === 'local') return const response = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).get('get.l2.pendingexits') if (response.status === 201) { @@ -1110,7 +805,7 @@ class NetworkService { if (this.networkGateway === 'local') return const response = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).get('get.l2.pendingexits') if (response.status === 201) { @@ -1130,7 +825,7 @@ class NetworkService { let monsterList = await GraphQLService.queryMonsterTransfer(this.account) const contract = new ethers.Contract( - allAddresses.BobaMonsters, + this.addresses.BobaMonsters, TuringMonsterJson.abi, this.L2Provider ) @@ -1138,12 +833,10 @@ class NetworkService { if (monsterList.hasOwnProperty('data')) { const monsters = monsterList.data.turingMonstersTransferEvents for (let i = 0; i < monsters.length; i++) { - // console.log("adding monster:", i + 1) const tokenId = monsters[i].tokenId const owner = await contract.ownerOf(tokenId) - //console.log("owner:", owner) if (owner.toLowerCase() === this.account.toLowerCase()) { - await this.addNFT(allAddresses.BobaMonsters, tokenId) + await this.addNFT(this.addresses.BobaMonsters, tokenId) } } await this.checkMonster() @@ -1155,9 +848,9 @@ class NetworkService { } async claimAuthenticatedTestnetTokens(tweetId) { - // Only Goerli + // Only Testnet const contract = new ethers.Contract( - addresses_Goerli.AuthenticatedFaucet, + this.addresses.AuthenticatedFaucet, AuthenticatedFaucetJson.abi, this.L2Provider, ).connect() @@ -1177,8 +870,10 @@ class NetworkService { try { + if (!this.addresses.BobaMonsters) return Number('0'); + const contract = new ethers.Contract( - allAddresses.BobaMonsters, + this.addresses.BobaMonsters, TuringMonsterJson.abi, this.L2Provider ) @@ -1189,12 +884,12 @@ class NetworkService { let topTop = 0 if(NFTs && Number(monsterBalance) > 0) { - //console.log("checking monsters") + for (const [ , value ] of Object.entries(NFTs)) { - //console.log(`${key} value: ${value.name}`) + if(value.name === 'TuringMonster') { const owner = await contract.ownerOf(value.tokenID) - //console.log("owner:", owner) + if(owner.toLowerCase() === this.account.toLowerCase()) { const attributes = { top: value.meta.attributes[3].value, @@ -1321,63 +1016,62 @@ class NetworkService { } } - async getGas() { + + async getBalances() { try { - const gasPrice2 = await this.L2Provider.getGasPrice() - //console.log("L2 gas", gasPrice2.toString()) - const block2 = await this.L2Provider.getBlockNumber() + let layer1Balances, layer2Balances; + + if (this.network === NETWORK.ETHEREUM) { + layer1Balances = [ + { + address: this.addresses.L1_ETH_Address, + addressL2: this.addresses.L2_ETH_Address, + currency: this.addresses.L1_ETH_Address, + symbol: 'ETH', + decimals: 18, + balance: new BN(0), + }, + ] - const gasPrice1 = await this.L1Provider.getGasPrice() - //console.log("L1 gas", gasPrice1.toString()) + layer2Balances = [ + { + address: this.addresses.L2_ETH_Address, + addressL1: this.addresses.L1_ETH_Address, + addressL2: this.addresses.L2_ETH_Address, + currency: this.addresses.L1_ETH_Address, + symbol: 'ETH', + decimals: 18, + balance: new BN(0), + }, + ] + } else { + layer1Balances = [ + { + address: this.addresses.L1_ETH_Address, + addressL2: this.addresses["TK_L2" + networkService.L1NativeTokenSymbol], + currency: this.addresses.L1_ETH_Address, + symbol: networkService.L1NativeTokenSymbol, + decimals: 18, + balance: new BN(0), + }, + ] - const block1 = await this.L1Provider.getBlockNumber() + layer2Balances = [ + { + address: this.addresses.L2_ETH_Address, + addressL1: this.addresses.TK_L1BOBA, + addressL2: this.addresses.L2_ETH_Address, + currency: this.addresses.TK_L1BOBA, + symbol: 'BOBA', + decimals: 18, + balance: new BN(0), + }, + ] - const gasData = { - gasL1: Number(logAmount(gasPrice1.toString(),9)).toFixed(0), - gasL2: Number(logAmount(gasPrice2.toString(),9)).toFixed(0), - blockL1: Number(block1), - blockL2: Number(block2), } - //console.log(gasData) - - return gasData - } catch (error) { - console.log("NS: getGas error:",error) - return error - } - - } - - async getBalances() { - - const layer1Balances = [ - { - address: allAddresses.L1_ETH_Address, - addressL2: allAddresses.L2_ETH_Address, - currency: allAddresses.L1_ETH_Address, - symbol: 'ETH', - decimals: 18, - balance: new BN(0), - }, - ] - - const layer2Balances = [ - { - address: allAddresses.L2_ETH_Address, - addressL1: allAddresses.L1_ETH_Address, - addressL2: allAddresses.L2_ETH_Address, - currency: allAddresses.L1_ETH_Address, - symbol: 'ETH', - decimals: 18, - balance: new BN(0), - }, - ] - - try { - // Always check ETH const layer1Balance = await this.L1Provider.getBalance(this.account) const layer2Balance = await this.L2Provider.getBalance(this.account) @@ -1386,15 +1080,15 @@ class NetworkService { layer2Balances[0].balance = new BN(layer2Balance.toString()) const state = store.getState() - const tA = Object.values(state.tokenList) + const tA = Object.values(state.tokenList); const tokenC = new ethers.Contract( - allAddresses.L1_ETH_Address, + this.addresses.L1_ETH_Address, L1ERC20Json.abi, this.L1Provider ) - const getERC20Balance = async(token, tokenAddress, layer, provider) => { + const getERC20Balance = async (token, tokenAddress, layer, provider) => { const balance = await tokenC.attach(tokenAddress).connect(provider).balanceOf(this.account) return { ...token, @@ -1408,41 +1102,32 @@ class NetworkService { const getBalancePromise = [] tA.forEach((token) => { - if (token.addressL1 === allAddresses.L1_ETH_Address) return - if (token.addressL2 === allAddresses.L2_ETH_Address) return if (token.addressL1 === null) return if (token.addressL2 === null) return + if (this.network === NETWORK.ETHEREUM) { + if(token.addressL1 === this.addresses.L1_ETH_Address) return + if(token.addressL2 === this.addresses.L2_ETH_Address) return + } else { + if (token.addressL1 === this.addresses.L1_ETH_Address) { + return getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - if (token.symbolL1 === 'xBOBA') { - //there is no L1 xBOBA - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv0') { - //there is no L1 WAGMIv0 - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv1') { - //there is no L1 WAGMIv1 - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv2') { - //there is no L2 WAGMIv2 - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv2-Oolong') { - //there is no L2 WAGMIv2OLO - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv3') { - //there is no L2 WAGMIv3 - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) - } - else if (token.symbolL1 === 'WAGMIv3-Oolong') { - //there is no L2 WAGMIv3OLO - getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) + } + if (token.addressL2 === this.addresses.L2_BOBA_Address) { + return getBalancePromise.push(getERC20Balance(token, token.addressL1, "L1", this.L1Provider)) + } } - else if (token.symbolL1 === 'OLO') { - //there is no L1 OLO + + if ([ + 'xBOBA', + 'WAGMIv0', + 'WAGMIv1', + 'WAGMIv2', + 'WAGMIv2-Oolong', + 'WAGMIv3', + 'WAGMIv3-Oolong', + 'OLO' + ].includes(token.symbolL1)) { + //there is no L1 xBOBA, WAGMIv0, WAGMIv1, WAGMIv2, WAGMIv2OLO, WAGMIv3, WAGMIv3OLO, OLO getBalancePromise.push(getERC20Balance(token, token.addressL2, "L2", this.L2Provider)) } else { @@ -1506,77 +1191,98 @@ class NetworkService { value_Wei_String }) { - updateSignatureStatus_depositTRAD(false) - try { const time_start = new Date().getTime() - console.log("TX start time:", time_start) + console.log('Deposit ETH L2 Txs start time:', time_start); let depositTX; - - if (!recipient) { - depositTX = await this.L1StandardBridgeContract - .connect(this.provider.getSigner()) - .depositETH( - this.L2GasLimit, - utils.formatBytes32String(new Date().getTime().toString()), - { - value: value_Wei_String - } - ) + if (this.network === NETWORK.ETHEREUM) { + if (!recipient) { + depositTX = await this.L1StandardBridgeContract + .connect(this.provider.getSigner()) + .depositETH( + this.L2GasLimit, + utils.formatBytes32String(new Date().getTime().toString()), + { + value: value_Wei_String + } + ) + } else { + depositTX = await this.L1StandardBridgeContract + .connect(this.provider.getSigner()) + .depositETHTo( + recipient, + this.L2GasLimit, + utils.formatBytes32String(new Date().getTime().toString()), + { + value: value_Wei_String + } + ) + } } else { - depositTX = await this.L1StandardBridgeContract - .connect(this.provider.getSigner()) - .depositETHTo( - recipient, - this.L2GasLimit, - utils.formatBytes32String(new Date().getTime().toString()), - { - value: value_Wei_String - } + if (!recipient) { + depositTX = await this.L1StandardBridgeContract + .connect(this.provider.getSigner()) + .depositNativeToken( + this.L2GasLimit, + utils.formatBytes32String(new Date().getTime().toString()), + { + value: value_Wei_String + } ) + } else { + depositTX = await this.L1StandardBridgeContract + .connect(this.provider.getSigner()) + .depositNativeTokenTo( + recipient, + this.L2GasLimit, + utils.formatBytes32String(new Date().getTime().toString()), + { + value: value_Wei_String + } + ) + } } - //at this point the tx has been submitted, and we are waiting... await depositTX.wait() - const block = await this.L1Provider.getTransaction(depositTX.hash) - console.log(' block:', block) - - //closes the Deposit modal - updateSignatureStatus_depositTRAD(true) - const opts = { fromBlock: -4000 } + const receipt = await this.watcher.waitForMessageReceipt(depositTX, opts) - console.log(' completed Deposit! L2 tx hash:', receipt.transactionHash) + const txReceipt = receipt.transactionReceipt; + console.log('completed Deposit! L2 tx hash:', receipt.transactionHash) const time_stop = new Date().getTime() console.log("TX finish time:", time_stop) + /* + // TODO: Investigate api-watcher failing with 502 + + const block = await this.L1Provider.getTransaction(depositTX.hash) const data = { "key": SPEED_CHECK, "hash": depositTX.hash, - "l1Tol2": false, //since we are going L2->L1 + "l1Tol2": true, //since we are going L1->L2 "startTime": time_start, "endTime": time_stop, "block": block.blockNumber, - "cdmHash": receipt.transactionHash, - "cdmBlock": receipt.blockNumber + "cdmHash": txReceipt.transactionHash, + "cdmBlock": txReceipt.blockNumber } console.log("Speed checker data payload:", data) const speed = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).post('send.crossdomainmessage', data) - console.log("Speed checker:", speed) + console.log("Speed checker:", speed) */ - return receipt + return txReceipt } catch(error) { console.log("NS: depositETHL2 error:",error) return error @@ -1596,7 +1302,7 @@ class NetworkService { try { const contract = new ethers.Contract( - allAddresses.BobaMonsters, + this.addresses.BobaMonsters, TuringMonsterJson.abi, this.L2Provider ) @@ -1611,7 +1317,7 @@ class NetworkService { const rawData = receipt.logs[3].topics[1] const numberHexString = rawData.slice(-64) let tokenID = parseInt(numberHexString, 16) - await this.addNFT( allAddresses.BobaMonsters, tokenID ) + await this.addNFT( this.addresses.BobaMonsters, tokenID ) return tx } catch (error) { @@ -1884,7 +1590,7 @@ class NetworkService { try { - if(currency === allAddresses.L2_ETH_Address) { + if(currency === this.addresses.L2_ETH_Address) { //we are sending ETH let wei = BigNumber.from(value_Wei_String) @@ -1935,7 +1641,7 @@ class NetworkService { try { - if(currency === allAddresses.L2_ETH_Address) { + if(currency === this.addresses.L2_ETH_Address) { gas_BN = await this.provider .getSigner() @@ -2065,7 +1771,7 @@ class NetworkService { let allowance_BN = await L2ERC20Contract.allowance( this.account, - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) //let depositAmount_BN = new BN(value_Wei_String) @@ -2073,7 +1779,7 @@ class NetworkService { if (depositAmount_BN.gt(allowance_BN)) { const approveStatus = await L2ERC20Contract.approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, value_Wei_String ) await approveStatus.wait() @@ -2094,7 +1800,7 @@ class NetworkService { ) { console.log("approveERC20_L1LP") - const approveContractAddress = allAddresses.L1LPAddress + const approveContractAddress = this.addresses.L1LPAddress let allowance_BN = BigNumber.from("0") let allowed = false @@ -2107,7 +1813,7 @@ class NetworkService { this.provider.getSigner() ) - if( currency !== allAddresses.L1_ETH_Address ) { + if( currency !== this.addresses.L1_ETH_Address ) { let allowance_BN = await ERC20Contract.allowance( this.account, @@ -2120,7 +1826,8 @@ class NetworkService { set to actual amount, unless current approval amount is equal to, or bigger than, the current approval value */ - if( allowance_BN.lt(BigNumber.from(value_Wei_String)) && + if (this.networkGateway === NETWORK.ETHEREUM + && allowance_BN.lt(BigNumber.from(value_Wei_String)) && (currency.toLowerCase() === allTokens.OMG.L1.toLowerCase()) ) { @@ -2170,10 +1877,9 @@ class NetworkService { async approveERC20( value_Wei_String, currency, - approveContractAddress = allAddresses.L1StandardBridgeAddress, + approveContractAddress = this.addresses.L1StandardBridgeAddress, contractABI = L1ERC20Json.abi ) { - try { const ERC20Contract = new ethers.Contract( @@ -2195,7 +1901,8 @@ class NetworkService { set to actual amount, unless current approval amount is equal to, or bigger than, the current approval value */ - if( allowance_BN.lt(BigNumber.from(value_Wei_String)) && + if ( this.networkGateway === NETWORK.ETHEREUM && + allowance_BN.lt(BigNumber.from(value_Wei_String)) && (currency.toLowerCase() === allTokens.OMG.L1.toLowerCase()) ) { @@ -2262,13 +1969,11 @@ class NetworkService { currency, currencyL2 }) { - updateSignatureStatus_depositTRAD(false) - const L1_TEST_Contract = this.L1_TEST_Contract.attach(currency) let allowance_BN = await L1_TEST_Contract.allowance( this.account, - allAddresses.L1StandardBridgeAddress + this.addresses.L1StandardBridgeAddress ) try { @@ -2277,14 +1982,15 @@ class NetworkService { set to actual amount, unless current approval amount is equal to, or bigger than, the current approval value */ - if( allowance_BN.lt(BigNumber.from(value_Wei_String)) && + if (this.networkGateway === NETWORK.ETHEREUM && + allowance_BN.lt(BigNumber.from(value_Wei_String)) && (currency.toLowerCase() === allTokens.OMG.L1.toLowerCase()) ) { console.log("Current OMG Token allowance too small - might need to reset to 0, unless it's already zero") if (allowance_BN.gt(BigNumber.from("0"))) { const approveOMG = await L1_TEST_Contract.approve( - allAddresses.L1StandardBridgeAddress, + this.addresses.L1StandardBridgeAddress, ethers.utils.parseEther("0") ) await approveOMG.wait() @@ -2295,7 +2001,7 @@ class NetworkService { //recheck the allowance allowance_BN = await L1_TEST_Contract.allowance( this.account, - allAddresses.L1StandardBridgeAddress + this.addresses.L1StandardBridgeAddress ) const allowed = allowance_BN.gte(BigNumber.from(value_Wei_String)) @@ -2304,7 +2010,7 @@ class NetworkService { //and now, the normal allowance transaction const approveStatus = await L1_TEST_Contract .connect(this.provider.getSigner()).approve( - allAddresses.L1StandardBridgeAddress, + this.addresses.L1StandardBridgeAddress, value_Wei_String ) await approveStatus.wait() @@ -2340,48 +2046,41 @@ class NetworkService { ) } - console.log("depositTxStatus:",depositTX) - //at this point the tx has been submitted, and we are waiting... await depositTX.wait() - const block = await this.L1Provider.getTransaction(depositTX.hash) - console.log(' block:', block) - - //closes the Deposit modal - updateSignatureStatus_depositTRAD(true) - const opts = { fromBlock: -4000 } const receipt = await this.watcher.waitForMessageReceipt(depositTX, opts) - console.log(' completed Deposit! L2 tx hash:', receipt.transactionHash) + const txReceipt = receipt.transactionReceipt; const time_stop = new Date().getTime() console.log("TX finish time:", time_stop) - const data = { - "key": SPEED_CHECK, - "hash": depositTX.hash, - "l1Tol2": true, - "startTime": time_start, - "endTime": time_stop, - "block": block.blockNumber, - "cdmHash": receipt.transactionHash, - "cdmBlock": receipt.blockNumber - } + // const block = await this.L1Provider.getTransaction(depositTX.hash) + // const data = { + // "key": SPEED_CHECK, + // "hash": depositTX.hash, + // "l1Tol2": true, + // "startTime": time_start, + // "endTime": time_stop, + // "block": block.blockNumber, + // "cdmHash": txReceipt.transactionHash, + // "cdmBlock": txReceipt.blockNumber + // } - console.log("Speed checker data payload:", data) + // console.log("Speed checker data payload:", data) - const speed = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('send.crossdomainmessage', data) + // const speed = await omgxWatcherAxiosInstance( + // this.networkConfig + // ).post('send.crossdomainmessage', data) - console.log("Speed checker:", speed) + // console.log("Speed checker:", speed) this.getBalances() - return receipt + return txReceipt } catch (error) { console.log("NS: depositErc20 error:", error) return error @@ -2396,7 +2095,7 @@ class NetworkService { try { const L2BillingContract = new ethers.Contract( - allAddresses.Proxy__BobaBillingContract, + this.addresses.Proxy__BobaBillingContract, L2BillingContractJson.abi, this.L2Provider, ) @@ -2407,43 +2106,54 @@ class NetworkService { const allowance = await this.checkAllowance( currencyAddress, - allAddresses.DiscretionaryExitFee + this.addresses.DiscretionaryExitFee ) const BobaAllowance = await this.checkAllowance( - allAddresses.TK_L2BOBA, - allAddresses.DiscretionaryExitFee + this.addresses.TK_L2BOBA, + this.addresses.DiscretionaryExitFee ) - if (utils.getAddress(currencyAddress) === utils.getAddress(allAddresses.TK_L2BOBA)) { - BobaApprovalAmount = BobaApprovalAmount.add(value) + if (this.networkGateway === NETWORK.ETHEREUM) { + // Should approve BOBA + if (utils.getAddress(currencyAddress) === utils.getAddress(this.addresses.TK_L2BOBA)) { + BobaApprovalAmount = BobaApprovalAmount.add(value) + } + + if ( BobaAllowance.lt(BobaApprovalAmount) ) { + const res = await this.approveERC20( + BobaApprovalAmount, + this.addresses.TK_L2BOBA, + this.addresses.DiscretionaryExitFee + ) + if (!res) return false + } + } - // Should approve BOBA - if ( BobaAllowance.lt(BobaApprovalAmount) ) { - const res = await this.approveERC20( - BobaApprovalAmount, - allAddresses.TK_L2BOBA, - allAddresses.DiscretionaryExitFee - ) - if (!res) return false + let otherField; + if (this.networkGateway === NETWORK.ETHEREUM) { + otherField = currencyAddress === this.addresses.L2_ETH_Address ? { value: value } : {} + } else { + otherField = currencyAddress === this.addresses.L2_ETH_Address ? + { value: value.add(BobaApprovalAmount) } : { value: BobaApprovalAmount } } // Should approve other tokens - if( currencyAddress !== allAddresses.L2_ETH_Address && - utils.getAddress(currencyAddress) !== utils.getAddress(allAddresses.TK_L2BOBA) && + if( currencyAddress !== this.addresses.L2_ETH_Address && + utils.getAddress(currencyAddress) !== utils.getAddress(this.addresses.TK_L2BOBA) && allowance.lt(value) ) { const res = await this.approveERC20( value, currencyAddress, - allAddresses.DiscretionaryExitFee + this.addresses.DiscretionaryExitFee ) if (!res) return false } const DiscretionaryExitFeeContract = new ethers.Contract( - allAddresses.DiscretionaryExitFee, + this.addresses.DiscretionaryExitFee, DiscretionaryExitFeeJson.abi, this.provider.getSigner() ) @@ -2454,8 +2164,7 @@ class NetworkService { value_Wei_String, this.L1GasLimit, utils.formatBytes32String(new Date().getTime().toString()), - currencyAddress === allAddresses.L2_ETH_Address ? - { value: value_Wei_String } : {} + otherField ) //everything submitted... waiting @@ -2464,12 +2173,6 @@ class NetworkService { //can close window now updateSignatureStatus_exitTRAD(true) - const opts = { - fromBlock: -4000 - } - const receipt = await this.watcher.waitForMessageReceipt(tx, opts) - console.log(' got L2->L1 receipt', receipt) - return tx } catch (error) { console.log("NS: exitBOBA error:", error) @@ -2481,12 +2184,14 @@ class NetworkService { /* Estimate cost of Classical Exit to L1 */ async getExitCost(currencyAddress) { + try { + let approvalCost_BN = BigNumber.from('0') const gasPrice = await this.L2Provider.getGasPrice() console.log("Classical exit gas price", gasPrice.toString()) - if( currencyAddress !== allAddresses.L2_ETH_Address ) { + if( currencyAddress !== this.addresses.L2_ETH_Address ) { const ERC20Contract = new ethers.Contract( currencyAddress, @@ -2495,7 +2200,7 @@ class NetworkService { ) const tx = await ERC20Contract.populateTransaction.approve( - allAddresses.DiscretionaryExitFee, + this.addresses.DiscretionaryExitFee, utils.parseEther('1.0') ) @@ -2505,17 +2210,28 @@ class NetworkService { } const DiscretionaryExitFeeContract = new ethers.Contract( - allAddresses.DiscretionaryExitFee, + this.addresses.DiscretionaryExitFee, DiscretionaryExitFeeJson.abi, this.provider.getSigner() ) + const L2BillingContract = new ethers.Contract( + this.addresses.Proxy__BobaBillingContract, + L2BillingContractJson.abi, + this.L2Provider, + ) + const exitFee = await L2BillingContract.exitFee() + let value = utils.parseEther('0.00001').add(exitFee) + if (this.networkGateway === NETWORK.ETHEREUM) { + value = utils.parseEther('0.00001') + } + const tx2 = await DiscretionaryExitFeeContract.populateTransaction.payAndWithdraw( - allAddresses.L2_ETH_Address, + this.addresses.L2_ETH_Address, utils.parseEther('0.00001'), this.L1GasLimit, ethers.utils.formatBytes32String(new Date().getTime().toString()), - { value: utils.parseEther('0.00001') } + { value } ) const gas_BN = await this.L2Provider.estimateGas({...tx2, from: this.gasEstimateAccount}) @@ -2527,8 +2243,12 @@ class NetworkService { const totalCost = utils.formatEther(cost_BN.add(approvalCost_BN)) console.log("Classical exit total cost (ETH):", totalCost) - //returns total cost in ETH - return totalCost + //returns total cost in ETH + return totalCost + } catch (error) { + console.log(error); + return 0; + } } /***********************************************/ @@ -2541,7 +2261,7 @@ class NetworkService { try{ const L1LPContract = new ethers.Contract( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, L1LPJson.abi, this.L1Provider ) @@ -2570,7 +2290,7 @@ class NetworkService { try{ const L2LPContract = new ethers.Contract( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, L2LPJson.abi, this.L2Provider ) @@ -2596,7 +2316,7 @@ class NetworkService { async getL1UserRewardFeeRate(tokenAddress) { try{ const L1LPContract = new ethers.Contract( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, L1LPJson.abi, this.L1Provider ) @@ -2612,7 +2332,7 @@ class NetworkService { async getL2UserRewardFeeRate(tokenAddress) { try { const L2LPContract = new ethers.Contract( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, L2LPJson.abi, this.L2Provider ) @@ -2633,7 +2353,7 @@ class NetworkService { const poolInfo = {} const userInfo = {} - let tokenAddressList = Object.keys(allTokens).reduce((acc, cur) => { + let tokenAddressList = Object.keys(this.tokenAddresses).reduce((acc, cur) => { if(cur !== 'xBOBA' && cur !== 'OLO' && cur !== 'WAGMIv0' && @@ -2642,13 +2362,13 @@ class NetworkService { cur !== 'WAGMIv2-Oolong' && cur !== 'WAGMIv3' && cur !== 'WAGMIv3-Oolong') { - acc.push(allTokens[cur].L1.toLowerCase()) + acc.push(this.tokenAddresses[cur].L1.toLowerCase()) } return acc - }, [allAddresses.L1_ETH_Address]) + }, [this.addresses.L1_ETH_Address]) const L1LPContract = new ethers.Contract( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, L1LPJson.abi, this.L1Provider ) @@ -2662,17 +2382,15 @@ class NetworkService { let tokenName let decimals - if (tokenAddress === allAddresses.L1_ETH_Address) { - //console.log("Getting eth balance:", tokenAddress) + if (tokenAddress === this.addresses.L1_ETH_Address) { //getting eth balance - tokenBalance = await this.L1Provider.getBalance(allAddresses.L1LPAddress) - tokenSymbol = 'ETH' - tokenName = 'Ethereum' + tokenBalance = await this.L1Provider.getBalance(this.addresses.L1LPAddress) + tokenSymbol = this.L1NativeTokenSymbol + tokenName = this.L1NativeTokenName decimals = 18 } else { //getting eth balance - //console.log("Getting balance for:", tokenAddress) - tokenBalance = await this.L1_TEST_Contract.attach(tokenAddress).connect(this.L1Provider).balanceOf(allAddresses.L1LPAddress) + tokenBalance = await this.L1_TEST_Contract.attach(tokenAddress).connect(this.L1Provider).balanceOf(this.addresses.L1LPAddress) const tokenInfoFiltered = this.tokenInfo.L1[utils.getAddress(tokenAddress)] if (tokenInfo) { tokenSymbol = tokenInfoFiltered.symbol @@ -2724,12 +2442,13 @@ class NetworkService { rewardDebt: Object.keys(token.userTokenInfo).length? token.userTokenInfo.rewardDebt.toString(): 0 } }) + return { poolInfo, userInfo } } async getL2LPInfo() { - const tokenAddressList = Object.keys(allTokens).reduce((acc, cur) => { + const tokenAddressList = Object.keys(this.tokenAddresses).reduce((acc, cur) => { if(cur !== 'xBOBA' && cur !== 'OLO' && cur !== 'WAGMIv0' && @@ -2740,18 +2459,18 @@ class NetworkService { cur !== 'WAGMIv3-Oolong' ) { acc.push({ - L1: allTokens[cur].L1.toLowerCase(), - L2: allTokens[cur].L2.toLowerCase() + L1: this.tokenAddresses[cur].L1.toLowerCase(), + L2: this.tokenAddresses[cur].L2.toLowerCase() }) } return acc }, [{ - L1: allAddresses.L1_ETH_Address, - L2: allAddresses.L2_ETH_Address + L1: this.addresses.L1_ETH_Address, + L2: this.addresses[`TK_L2${this.L1NativeTokenSymbol}`] }]) const L2LPContract = new ethers.Contract( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, L2LPJson.abi, this.L2Provider ) @@ -2768,13 +2487,13 @@ class NetworkService { let tokenName let decimals - if (tokenAddress === allAddresses.L2_ETH_Address) { - tokenBalance = await this.L2Provider.getBalance(allAddresses.L2LPAddress) - tokenSymbol = 'ETH' - tokenName = 'Ethereum' + if (tokenAddress === this.addresses.L2_ETH_Address) { + tokenBalance = await this.L2Provider.getBalance(this.addresses.L2LPAddress) + tokenSymbol = this.network === NETWORK.ETHEREUM ? 'ETH' : 'BOBA' + tokenName = this.network === NETWORK.ETHEREUM ? 'Ethereum' : 'BOBA Token' decimals = 18 } else { - tokenBalance = await this.L2_TEST_Contract.attach(tokenAddress).connect(this.L2Provider).balanceOf(allAddresses.L2LPAddress) + tokenBalance = await this.L2_TEST_Contract.attach(tokenAddress).connect(this.L2Provider).balanceOf(this.addresses.L2LPAddress) const tokenInfoFiltered = this.tokenInfo.L2[utils.getAddress(tokenAddress)] if (tokenInfo) { tokenSymbol = tokenInfoFiltered.symbol @@ -2837,7 +2556,7 @@ class NetworkService { let otherField = {} - if( currency === allAddresses.L1_ETH_Address || currency === allAddresses.L2_ETH_Address ) { + if( currency === this.addresses.L1_ETH_Address || currency === this.addresses.L2_ETH_Address ) { // add value field for ETH otherField['value'] = value_Wei_String } @@ -2875,12 +2594,12 @@ class NetworkService { // First, we need the approval cost // not relevant to ETH - if( currency !== allAddresses.L2_ETH_Address ) { + if( currency !== this.addresses.L2_ETH_Address ) { const tx1 = await this.BobaContract .populateTransaction .approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, utils.parseEther('1.0'), otherField ) @@ -2890,6 +2609,12 @@ class NetworkService { console.log("Approve cost in ETH:", utils.formatEther(approvalCost_BN)) } + if (this.networkGateway !== NETWORK.ETHEREUM) { + otherField = { + ...otherField, + value: utils.parseEther('1.0') + } + } // Second, we need the addLiquidity cost // all ERC20s will be the same, so use the BOBA contract const tx2 = await this.L2LPContract @@ -2985,7 +2710,7 @@ class NetworkService { .clientDepositL1( value_Wei_String, currency, - currency === allAddresses.L1_ETH_Address ? { value: value_Wei_String } : {} + currency === this.addresses.L1_ETH_Address ? { value: value_Wei_String } : {} ) console.log("depositTX",depositTX) @@ -2998,35 +2723,38 @@ class NetworkService { updateSignatureStatus_depositLP(true) - const opts = { - fromBlock: -4000 - } - const receipt = await this.watcher.waitForMessageReceipt(depositTX, opts) - console.log(' completed swap-on ! L2 tx hash:', receipt.transactionHash) - - const time_stop = new Date().getTime() - console.log("TX finish time:", time_stop) + // TODO: Below part is disabled - const data = { - "key": SPEED_CHECK, - "hash": depositTX.hash, - "l1Tol2": true, - "startTime": time_start, - "endTime": time_stop, - "block": block.blockNumber, - "cdmHash": receipt.transactionHash, - "cdmBlock": receipt.blockNumber - } + /* + const opts = { + fromBlock: -4000 + } + const receipt = await this.watcher.waitForMessageReceipt(depositTX, opts) + console.log(' completed swap-on ! L2 tx hash:', receipt.transactionHash) + + const time_stop = new Date().getTime() + console.log("TX finish time:", time_stop) + + const data = { + "key": SPEED_CHECK, + "hash": depositTX.hash, + "l1Tol2": true, + "startTime": time_start, + "endTime": time_stop, + "block": block.blockNumber, + "cdmHash": receipt.transactionHash, + "cdmBlock": receipt.blockNumber + } - console.log("Speed checker data payload:", data) + console.log("Speed checker data payload:", data) - const speed = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('send.crossdomainmessage', data) + const speed = await omgxWatcherAxiosInstance( + this.networkConfig + ).post('send.crossdomainmessage', data) - console.log("Speed checker:", speed) - - return receipt + console.log("Speed checker:", speed) + */ + return true } catch (error) { console.log("NS: depositL1LP error:", error) @@ -3098,7 +2826,7 @@ class NetworkService { console.log("Speed checker data payload:", data) const speed = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).post('send.crossdomainmessage', data) console.log("Speed checker:", speed) @@ -3117,7 +2845,7 @@ class NetworkService { async L1LPPending(tokenAddress) { const L1pending = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).get('get.l2.pendingexits', {}) const pendingFast = L1pending.data.filter(i => { @@ -3154,15 +2882,15 @@ class NetworkService { let tokenAddressLC = tokenAddress.toLowerCase() if ( - tokenAddressLC === allAddresses.L2_ETH_Address || - tokenAddressLC === allAddresses.L1_ETH_Address + tokenAddressLC === this.addresses.L2_ETH_Address || + tokenAddressLC === this.addresses.L1_ETH_Address ) { - balance = await this.L1Provider.getBalance(allAddresses.L1LPAddress) + balance = await this.L1Provider.getBalance(this.addresses.L1LPAddress) } else { balance = await this.L1_TEST_Contract .attach(tokenAddress) .connect(this.L1Provider) - .balanceOf(allAddresses.L1LPAddress) + .balanceOf(this.addresses.L1LPAddress) } return balance.toString() @@ -3178,16 +2906,16 @@ class NetworkService { let tokenAddressLC = tokenAddress.toLowerCase() if ( - tokenAddressLC === allAddresses.L2_ETH_Address || - tokenAddressLC === allAddresses.L1_ETH_Address + tokenAddressLC === this.addresses.L2_BOBA_Address || + tokenAddressLC === this.addresses.L1_ETH_Address ) { //We are dealing with ETH balance = await this.L2_ETH_Contract.connect(this.L2Provider).balanceOf( - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) } else { balance = await this.L2_TEST_Contract.attach(tokenAddress).connect(this.L2Provider).balanceOf( - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) } @@ -3200,7 +2928,7 @@ class NetworkService { async L1LPLiquidity(tokenAddress) { const L1LPContractNS = new ethers.Contract( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, L1LPJson.abi, this.L1Provider ) @@ -3221,7 +2949,7 @@ class NetworkService { async L2LPLiquidity(tokenAddress) { const L2LPContractNS = new ethers.Contract( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, L2LPJson.abi, this.L2Provider ) @@ -3244,7 +2972,7 @@ class NetworkService { const gasPrice = await this.L2Provider.getGasPrice() console.log("Fast exit gas price", gasPrice.toString()) - if( currencyAddress !== allAddresses.L2_ETH_Address ) { + if( currencyAddress !== this.addresses.L2_ETH_Address ) { const ERC20Contract = new ethers.Contract( currencyAddress, @@ -3255,7 +2983,7 @@ class NetworkService { const tx = await ERC20Contract .populateTransaction .approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, utils.parseEther('1.0') ) @@ -3264,20 +2992,35 @@ class NetworkService { console.log("Approve cost in ETH:", utils.formatEther(approvalCost_BN)) } + const L2BillingContract = new ethers.Contract( + this.addresses.Proxy__BobaBillingContract, + L2BillingContractJson.abi, + this.L2Provider, + ) + + const approvalAmount = await L2BillingContract.exitFee() + + let value; + if (this.networkGateway === NETWORK.ETHEREUM) { + value = currencyAddress === this.addresses.L2_ETH_Address ? { value: '1' } : {}; + } else { + value = currencyAddress === this.addresses.L2_ETH_Address ? { value: approvalAmount.add('1') } : { value: approvalAmount }; + } + //in some cases zero not allowed const tx2 = await this.L2LPContract .connect(this.provider.getSigner()) .populateTransaction .clientDepositL2( - currencyAddress === allAddresses.L2_ETH_Address ? '1' : '0', //ETH does not allow zero + currencyAddress === this.addresses.L2_ETH_Address ? '1' : '0', //ETH does not allow zero currencyAddress, - currencyAddress === allAddresses.L2_ETH_Address ? { value : '1'} : {} + value ) const depositGas_BN = await this.L2Provider.estimateGas({...tx2, from: this.gasEstimateAccount}) let l1SecurityFee = BigNumber.from('0') - if (this.networkGateway === 'mainnet') { + if (this.networkType === NETWORK_TYPE.MAINNET) { delete tx2.from l1SecurityFee = await this.gasOracleContract.getL1Fee( utils.serializeTransaction(tx2) @@ -3304,7 +3047,7 @@ class NetworkService { const gasPrice = await this.L1Provider.getGasPrice() console.log("Fast deposit gas price", gasPrice.toString()) - if( currencyAddress !== allAddresses.L1_ETH_Address ) { + if( currencyAddress !== this.addresses.L1_ETH_Address ) { const ERC20Contract = new ethers.Contract( currencyAddress, @@ -3313,7 +3056,7 @@ class NetworkService { ) const tx = await ERC20Contract.populateTransaction.approve( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, utils.parseEther('1.0') ) @@ -3325,9 +3068,9 @@ class NetworkService { //in some cases zero not allowed const tx2 = await this.L1LPContract .connect(this.provider.getSigner()).populateTransaction.clientDepositL1( - currencyAddress === allAddresses.L1_ETH_Address ? '1' : '0', //ETH does not allow zero + currencyAddress === this.addresses.L1_ETH_Address ? '1' : '0', //ETH does not allow zero currencyAddress, - currencyAddress === allAddresses.L1_ETH_Address ? { value : '1'} : {} + currencyAddress === this.addresses.L1_ETH_Address ? { value : '1'} : {} ) const depositGas_BN = await this.L1Provider.estimateGas(tx2) @@ -3359,7 +3102,7 @@ class NetworkService { ) const tx = await ERC20Contract.populateTransaction.approve( - allAddresses.L1LPAddress, + this.addresses.L1LPAddress, utils.parseEther('0') ) @@ -3404,20 +3147,20 @@ class NetworkService { let gasPrice = await this.L2Provider.getGasPrice() console.log("Fast exit gas price", gasPrice.toString()) - if( currencyAddress === allAddresses.L2_ETH_Address ) { + if( currencyAddress === this.addresses.L2_ETH_Address ) { balance_BN = await this.L2Provider.getBalance(this.account) } const L2BillingContract = new ethers.Contract( - allAddresses.Proxy__BobaBillingContract, + this.addresses.Proxy__BobaBillingContract, L2BillingContractJson.abi, this.L2Provider, ) let BobaApprovalAmount = await L2BillingContract.exitFee() const BobaAllowance = await this.checkAllowance( - allAddresses.TK_L2BOBA, - allAddresses.L2LPAddress, + this.addresses.TK_L2BOBA, + this.addresses.L2LPAddress, ) try { @@ -3425,15 +3168,15 @@ class NetworkService { if (BobaAllowance.lt(BobaApprovalAmount)) { const approveStatus = await this.approveERC20( BobaApprovalAmount, - allAddresses.TK_L2BOBA, - allAddresses.L2LPAddress + this.addresses.TK_L2BOBA, + this.addresses.L2LPAddress ) if (!approveStatus) return false } // Approve other tokens - if( currencyAddress !== allAddresses.L2_ETH_Address && - utils.getAddress(currencyAddress) !== utils.getAddress(allAddresses.TK_L2BOBA) + if( currencyAddress !== this.addresses.L2_ETH_Address && + utils.getAddress(currencyAddress) !== utils.getAddress(this.addresses.TK_L2BOBA) ) { const L2ERC20Contract = new ethers.Contract( currencyAddress, @@ -3448,7 +3191,7 @@ class NetworkService { let allowance_BN = await L2ERC20Contract.allowance( this.account, - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) console.log("Allowance:",utils.formatEther(allowance_BN)) @@ -3456,7 +3199,7 @@ class NetworkService { //Estimate gas const tx = await L2ERC20Contract.populateTransaction.approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, balance_BN ) @@ -3465,7 +3208,7 @@ class NetworkService { console.log("Cost to Approve (ETH):", utils.formatEther(approvalCost_BN)) const approveStatus = await L2ERC20Contract.approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, balance_BN ) await approveStatus.wait() @@ -3483,7 +3226,7 @@ class NetworkService { .connect(this.provider.getSigner()).populateTransaction.clientDepositL2( balance_BN, currencyAddress, - currencyAddress === allAddresses.L2_ETH_Address ? { value : '1' } : {} + currencyAddress === this.addresses.L2_ETH_Address ? { value : '1' } : {} ) let depositGas_BN = await this.L2Provider.estimateGas(tx2) @@ -3505,7 +3248,7 @@ class NetworkService { let depositCost_BN = depositGas_BN.mul(gasPrice).add(l1SecurityFee) console.log("Deposit gas cost (ETH)", utils.formatEther(depositCost_BN)) - if(currencyAddress === allAddresses.L2_ETH_Address) { + if(currencyAddress === this.addresses.L2_ETH_Address) { //if fee token, need to consider cost to exit balance_BN = balance_BN.sub(depositCost_BN) } @@ -3524,7 +3267,7 @@ class NetworkService { .connect(this.provider.getSigner()).clientDepositL2( balance_BN, currencyAddress, - currencyAddress === allAddresses.L2_ETH_Address ? { value : balance_BN.sub(depositCost_BN) } : {} + currencyAddress === this.addresses.L2_ETH_Address ? { value : balance_BN.sub(depositCost_BN) } : {} ) //at this point the tx has been submitted, and we are waiting... @@ -3540,7 +3283,9 @@ class NetworkService { fromBlock: -4000 } const receipt = await this.fastWatcher.waitForMessageReceipt(depositTX, opts) - console.log(' completed Deposit! L1 tx hash:', receipt.transactionHash) + const txReceipt = receipt.transactionReceipt; + + console.log(' completed Deposit! L1 tx hash:', txReceipt.transactionHash) const time_stop = new Date().getTime() console.log("TX finish time:", time_stop) @@ -3552,14 +3297,14 @@ class NetworkService { "startTime": time_start, "endTime": time_stop, "block": block.blockNumber, - "cdmHash": receipt.transactionHash, - "cdmBlock": receipt.blockNumber + "cdmHash": txReceipt.transactionHash, + "cdmBlock": txReceipt.blockNumber } console.log("Speed checker data payload:", data) const speed = await omgxWatcherAxiosInstance( - this.networkGateway + this.networkConfig ).post('send.crossdomainmessage', data) console.log("Speed checker:", speed) @@ -3581,34 +3326,38 @@ class NetworkService { console.log("depositL2LP currencyAddress",currencyAddress) const L2BillingContract = new ethers.Contract( - allAddresses.Proxy__BobaBillingContract, + this.addresses.Proxy__BobaBillingContract, L2BillingContractJson.abi, this.L2Provider, ) let BobaApprovalAmount = await L2BillingContract.exitFee() const BobaAllowance = await this.checkAllowance( - allAddresses.TK_L2BOBA, - allAddresses.L2LPAddress, + this.addresses.TK_L2BOBA, + this.addresses.L2LPAddress, ) try { - // Approve BOBA first - if (utils.getAddress(currencyAddress) === utils.getAddress(allAddresses.TK_L2BOBA)) { - BobaApprovalAmount = BobaApprovalAmount.add(BigNumber.from(value_Wei_String)) - } - if (BobaAllowance.lt(BobaApprovalAmount)) { - const approveStatus = await this.approveERC20( - BobaApprovalAmount, - allAddresses.TK_L2BOBA, - allAddresses.L2LPAddress - ) - if (!approveStatus) return false + + if (this.networkGateway === NETWORK.ETHEREUM) { + // Approve BOBA first only when the Boba is not native token. + if (utils.getAddress(currencyAddress) === utils.getAddress(this.addresses.TK_L2BOBA)) { + BobaApprovalAmount = BobaApprovalAmount.add(BigNumber.from(value_Wei_String)) + } + if (BobaAllowance.lt(BobaApprovalAmount)) { + const approveStatus = await this.approveERC20( + BobaApprovalAmount, + this.addresses.TK_L2BOBA, + this.addresses.L2LPAddress + ) + if (!approveStatus) return false + } + } // Approve other tokens - if( currencyAddress !== allAddresses.L2_ETH_Address && - utils.getAddress(currencyAddress) !== utils.getAddress(allAddresses.TK_L2BOBA) + if( currencyAddress !== this.addresses.L2_ETH_Address && + utils.getAddress(currencyAddress) !== utils.getAddress(this.addresses.TK_L2BOBA) ) { const L2ERC20Contract = new ethers.Contract( @@ -3619,14 +3368,14 @@ class NetworkService { let allowance_BN = await L2ERC20Contract.allowance( this.account, - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) let depositAmount_BN = BigNumber.from(value_Wei_String) if (depositAmount_BN.gt(allowance_BN)) { const approveStatus = await L2ERC20Contract.approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, value_Wei_String ) await approveStatus.wait() @@ -3637,11 +3386,18 @@ class NetworkService { const time_start = new Date().getTime() console.log("TX start time:", time_start) + let otherField; + if (this.networkGateway === NETWORK.ETHEREUM) { + otherField= currencyAddress === this.addresses.L2_ETH_Address ? { value: value_Wei_String } : {} + } else { + otherField= currencyAddress === this.addresses.L2_ETH_Address ? { value: BobaApprovalAmount.add(value_Wei_String) } : {value: BobaApprovalAmount} + } + const depositTX = await this.L2LPContract .connect(this.provider.getSigner()).clientDepositL2( value_Wei_String, currencyAddress, - currencyAddress === allAddresses.L2_ETH_Address ? { value: value_Wei_String } : {} + otherField, ) //at this point the tx has been submitted, and we are waiting... @@ -3653,35 +3409,36 @@ class NetworkService { //closes the modal updateSignatureStatus_exitLP(true) - const opts = { - fromBlock: -4000 - } - const receipt = await this.fastWatcher.waitForMessageReceipt(depositTX, opts) - console.log(' completed Deposit! L1 tx hash:', receipt.transactionHash) - - const time_stop = new Date().getTime() - console.log("TX finish time:", time_stop) - - const data = { - "key": SPEED_CHECK, - "hash": depositTX.hash, - "l1Tol2": false, //since we are going L2->L1 - "startTime": time_start, - "endTime": time_stop, - "block": block.blockNumber, - "cdmHash": receipt.transactionHash, - "cdmBlock": receipt.blockNumber - } + // const opts = { + // fromBlock: -4000 + // } + // const receipt = await this.fastWatcher.waitForMessageReceipt(depositTX, opts) + // const txReceipt = receipt.transactionReceipt; + // console.log(' completed Deposit! L1 tx hash:', txReceipt.transactionHash) + + // const time_stop = new Date().getTime() + // console.log("TX finish time:", time_stop) + + // const data = { + // "key": SPEED_CHECK, + // "hash": depositTX.hash, + // "l1Tol2": false, //since we are going L2->L1 + // "startTime": time_start, + // "endTime": time_stop, + // "block": block.blockNumber, + // "cdmHash": txReceipt.transactionHash, + // "cdmBlock": txReceipt.blockNumber + // } - console.log("Speed checker data payload:", data) + // console.log("Speed checker data payload:", data) - const speed = await omgxWatcherAxiosInstance( - this.networkGateway - ).post('send.crossdomainmessage', data) + // const speed = await omgxWatcherAxiosInstance( + // this.networkConfig + // ).post('send.crossdomainmessage', data) - console.log("Speed checker:", speed) + // console.log("Speed checker:", speed) - return receipt + return true } catch (error) { console.log("NS: depositL2LP error:", error) return error @@ -3854,7 +3611,7 @@ class NetworkService { if( !this.delegateContract ) return try { - const delegateCheck = await this.delegateContract.attach(allAddresses.GovernorBravoDelegator) + const delegateCheck = await this.delegateContract.attach(this.addresses.GovernorBravoDelegator) const rawThreshold = await delegateCheck.proposalThreshold() return { proposalThreshold: formatEther(rawThreshold) } } catch (error) { @@ -3889,12 +3646,12 @@ class NetworkService { /* let tokenIds = payload.tokenIds // create proposal only on latest contracts. - const delegateCheck = await this.delegateContract.attach(allAddresses.GovernorBravoDelegatorV2) + const delegateCheck = await this.delegateContract.attach(this.addresses.GovernorBravoDelegatorV2) */ // FIXME: Ve DAO Till here - const delegateCheck = await this.delegateContract.attach(allAddresses.GovernorBravoDelegator) + const delegateCheck = await this.delegateContract.attach(this.addresses.GovernorBravoDelegator) if( payload.action === 'text-proposal' ) { address = ['0x000000000000000000000000000000000000dEaD'] @@ -3908,7 +3665,7 @@ class NetworkService { value2 = Number(payload.value[1]) value3 = Number(payload.value[2]) description = `Change L1 LP Bridge fee to ${value1}, ${value2}, and ${value3} integer percent` - address = [allAddresses.L2LPAddress] + address = [this.addresses.L2LPAddress] callData = [ethers.utils.defaultAbiCoder.encode( ['uint256','uint256','uint256'], [value1, value2, value3] @@ -3920,7 +3677,7 @@ class NetworkService { value2 = Number(payload.value[1]) value3 = Number(payload.value[2]) description = `Change L2 LP Bridge fee to ${value1}, ${value2}, and ${value3} integer percent` - address = [allAddresses.L2LPAddress] + address = [this.addresses.L2LPAddress] callData = [ethers.utils.defaultAbiCoder.encode( ['uint256','uint256','uint256'], [value1, value2, value3] @@ -3969,8 +3726,8 @@ class NetworkService { if (!this.delegateContract || this.networkGateway === 'goerli') return - const delegateCheckV1 = await this.delegateContract.attach(allAddresses.GovernorBravoDelegator) - const delegateCheckV2 = await this.delegateContract.attach(allAddresses.GovernorBravoDelegatorV2) + const delegateCheckV1 = await this.delegateContract.attach(this.addresses.GovernorBravoDelegator) + const delegateCheckV2 = await this.delegateContract.attach(this.addresses.GovernorBravoDelegatorV2) try { @@ -3980,13 +3737,13 @@ class NetworkService { const descriptionList = await GraphQLService.queryBridgeProposalCreated() const proposalGroup = groupBy(descriptionList.data.governorProposalCreateds, 'to'); - const delegatorList = [ allAddresses.GovernorBravoDelegator, allAddresses.GovernorBravoDelegatorV2 ]; + const delegatorList = [ this.addresses.GovernorBravoDelegator, this.addresses.GovernorBravoDelegatorV2 ]; for (let delegator of delegatorList) { let delegateCheck; - if (delegator === allAddresses.GovernorBravoDelegator) { + if (delegator === this.addresses.GovernorBravoDelegator) { delegateCheck = delegateCheckV1; - } else if(delegator === allAddresses.GovernorBravoDelegatorV2) { + } else if(delegator === this.addresses.GovernorBravoDelegatorV2) { delegateCheck = delegateCheckV2; } const proposals = proposalGroup[ delegator.toLowerCase() ] @@ -4055,7 +3812,7 @@ class NetworkService { hasLiveProposal } } catch (error) { - console.log("NS: fetchProposals error:",error) + console.log("NS: fetchProposalsVeDao error:",error) return error } } @@ -4065,7 +3822,7 @@ class NetworkService { if (!this.delegateContract) return try { - const delegateCheck = await this.delegateContract.attach(allAddresses.GovernorBravoDelegatorV2) + const delegateCheck = await this.delegateContract.attach(this.addresses.GovernorBravoDelegatorV2) if (this.account) { const receipt = await delegateCheck.getReceipt(Number(proposalId), tokenId); @@ -4094,7 +3851,7 @@ class NetworkService { try { const delegateCheck = await this.delegateContract .connect(this.provider.getSigner()) - .attach(allAddresses.GovernorBravoDelegatorV2) + .attach(this.addresses.GovernorBravoDelegatorV2) const res = await delegateCheck.castVote(id, userVote, tokenIds) @@ -4118,7 +3875,7 @@ class NetworkService { try { const delegateCheck = await this.delegateContract .connect(this.provider.getSigner()) - .attach(allAddresses.GovernorBravoDelegator) + .attach(this.addresses.GovernorBravoDelegator) let res = delegateCheck.queue(Number(proposalID)) return res } catch(error) { @@ -4140,7 +3897,7 @@ class NetworkService { try { const delegateCheck = await this.delegateContract .connect(this.provider.getSigner()) - .attach(allAddresses.GovernorBravoDelegator) + .attach(this.addresses.GovernorBravoDelegator) let res = delegateCheck.execute(Number(proposalID)) return res } catch(error) { @@ -4163,23 +3920,19 @@ class NetworkService { try { const FixedSavings = new ethers.Contract( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, L2SaveJson.abi, this.provider.getSigner() ) - console.log("FixedSavings.address:",FixedSavings.address) - let allowance_BN = await this.BobaContract .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.BobaFixedSavings + this.addresses.BobaFixedSavings ) - console.log("Allowance:", allowance_BN.toString()) let depositAmount_BN = BigNumber.from(value_Wei_String) - console.log("Deposit:", depositAmount_BN) let approveAmount_BN = depositAmount_BN.add(BigNumber.from('1000000000000')) @@ -4189,11 +3942,10 @@ class NetworkService { const approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, approveAmount_BN ) - const TX = await approveStatus.wait() - console.log("approveStatus:", TX) + await approveStatus.wait() } else { console.log("Allowance is sufficient:", allowance_BN.toString(), depositAmount_BN.toString()) @@ -4234,7 +3986,7 @@ class NetworkService { .connect(this.provider) .allowance( this.gasEstimateAccount, - allAddresses.BobaFixedSavings + this.addresses.BobaFixedSavings ) console.log("benchmarkAllowance_BN",allowance_BN.toString()) @@ -4243,7 +3995,7 @@ class NetworkService { .connect(this.provider.getSigner()) .populateTransaction .approve( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, allowance_BN.toString(), ) @@ -4253,7 +4005,7 @@ class NetworkService { // third, we need the stake cost const FixedSavings = new ethers.Contract( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, L2SaveJson.abi, this.provider ) @@ -4288,7 +4040,7 @@ class NetworkService { try { const FixedSavings = new ethers.Contract( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, L2SaveJson.abi, this.provider.getSigner() ) @@ -4310,7 +4062,7 @@ class NetworkService { try { const FixedSavings = new ethers.Contract( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, L2SaveJson.abi, this.L2Provider ) @@ -4329,57 +4081,57 @@ class NetworkService { let allowance_BN = null let approveStatus = null - if(allAddresses.hasOwnProperty('BobaFixedSavings')) { + if(this.addresses.hasOwnProperty('BobaFixedSavings')) { allowance_BN = await this.BobaContract .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.BobaFixedSavings + this.addresses.BobaFixedSavings ) console.log("Fixed Savings Allowance", allowance_BN.toString()) approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, approvalAmount ) await approveStatus.wait() console.log("Fixed Savings Approval", approveStatus) } - if(allAddresses.hasOwnProperty('DiscretionaryExitFee')) { + if(this.addresses.hasOwnProperty('DiscretionaryExitFee')) { allowance_BN = await this.BobaContract .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.DiscretionaryExitFee + this.addresses.DiscretionaryExitFee ) console.log("DiscretionaryExitFee Allowance", allowance_BN.toString()) approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.DiscretionaryExitFee, + this.addresses.DiscretionaryExitFee, approvalAmount ) await approveStatus.wait() console.log("DiscretionaryExitFee Approval", approveStatus) } - if(allAddresses.hasOwnProperty('L2LPAddress')) { + if(this.addresses.hasOwnProperty('L2LPAddress')) { allowance_BN = await this.BobaContract .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.L2LPAddress + this.addresses.L2LPAddress ) console.log("L2LP", allowance_BN.toString()) approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.L2LPAddress, + this.addresses.L2LPAddress, approvalAmount ) await approveStatus.wait() @@ -4398,7 +4150,7 @@ class NetworkService { try { const FixedSavings = new ethers.Contract( - allAddresses.BobaFixedSavings, + this.addresses.BobaFixedSavings, L2SaveJson.abi, this.L2Provider ) @@ -4511,7 +4263,7 @@ class NetworkService { /***********************************************/ async getExitFeeFromBillingContract() { const L2BillingContract = new ethers.Contract( - allAddresses.Proxy__BobaBillingContract, + this.addresses.Proxy__BobaBillingContract, L2BillingContractJson.abi, this.L2Provider, ) @@ -4547,7 +4299,7 @@ class NetworkService { try { const ve = new ethers.Contract( - allAddresses.Ve_BOBA, + this.addresses.Ve_BOBA, veJson.abi, this.provider.getSigner() ) @@ -4556,7 +4308,7 @@ class NetworkService { .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.Ve_BOBA + this.addresses.Ve_BOBA ) let depositAmount_BN = BigNumber.from(value_Wei_String) @@ -4568,7 +4320,7 @@ class NetworkService { const approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.Ve_BOBA, + this.addresses.Ve_BOBA, approveAmount_BN ) const TX = await approveStatus.wait() @@ -4604,7 +4356,7 @@ class NetworkService { try { const ve = new ethers.Contract( - allAddresses.Ve_BOBA, //check ve address is present + this.addresses.Ve_BOBA, //check ve address is present veJson.abi, this.provider.getSigner() ) @@ -4631,7 +4383,7 @@ class NetworkService { } try { const ve = new ethers.Contract( - allAddresses.Ve_BOBA, //check ve address is present + this.addresses.Ve_BOBA, //check ve address is present veJson.abi, this.provider.getSigner() ) @@ -4640,7 +4392,7 @@ class NetworkService { .connect(this.provider.getSigner()) .allowance( this.account, - allAddresses.Ve_BOBA + this.addresses.Ve_BOBA ) let depositAmount_BN = BigNumber.from(value_Wei_String) @@ -4652,7 +4404,7 @@ class NetworkService { const approveStatus = await this.BobaContract .connect(this.provider.getSigner()) .approve( - allAddresses.Ve_BOBA, + this.addresses.Ve_BOBA, approveAmount_BN ) await approveStatus.wait() @@ -4689,7 +4441,7 @@ class NetworkService { try { const ve = new ethers.Contract( - allAddresses.Ve_BOBA, //check ve address is present + this.addresses.Ve_BOBA, //check ve address is present veJson.abi, this.provider.getSigner() ) @@ -4717,13 +4469,13 @@ class NetworkService { try { const ve = new ethers.Contract( - allAddresses.Ve_BOBA, //check ve address is present + this.addresses.Ve_BOBA, //check ve address is present veJson.abi, this.provider ) const baseVoter = new ethers.Contract( - allAddresses.BASE_V1_VOTER, + this.addresses.BASE_V1_VOTER, voterJson.abi, this.provider ) @@ -4776,16 +4528,16 @@ class NetworkService { async getAltL1DepositFee() { if (this.account === null) { - console.log('NS: depositErc20ToL1() error - called but account === null') + console.log('NS: getAltL1DepositFee() error - called but account === null') return } try { - const pResponse = supportedAltL1Chains.map(async (type) => { - let L0_ETH_ENDPOINT = allAddresses.Layer_Zero_Endpoint; - let ETH_L1_BOBA_ADDRESS = allAddresses.TK_L1BOBA; - let L0_TARGET_CHAIN_ID = l0AllProtocols[type].Layer_Zero_ChainId; - let ALT_L1_BOBA_ADDRESS = allAddresses[`Proxy__EthBridgeTo${type}`]; - let PROXY_ETH_L1_BRIDGE_ADDRESS_TO = allAddresses[`${type}_TK_BOBA`]; + const pResponse = this.supportedAltL1Chains.map(async (type) => { + let L0_ETH_ENDPOINT = this.addresses.Layer_Zero_Endpoint; + let ETH_L1_BOBA_ADDRESS = this.addresses.TK_L1BOBA; + let L0_TARGET_CHAIN_ID = this.addresses.layerZeroTargetChainID; + let ALT_L1_BOBA_ADDRESS = this.addresses[`Proxy__EthBridgeTo${type}`]; + let PROXY_ETH_L1_BRIDGE_ADDRESS_TO = this.addresses[`${type}_TK_BOBA`]; // Layer zero doesn't support moonbase // return 0 for those bridges that haven't been implemented yet @@ -4855,11 +4607,11 @@ class NetworkService { return } try { - let L0_ETH_ENDPOINT = allAddresses.Layer_Zero_Endpoint; - let L0_TARGET_CHAIN_ID = l0AllProtocols[type].Layer_Zero_ChainId; - let ETH_L1_BOBA_ADDRESS = allAddresses.TK_L1BOBA; - let PROXY_ETH_L1_BRIDGE_ADDRESS_TO = allAddresses[`Proxy__EthBridgeTo${type}`]; - let ALT_L1_BOBA_ADDRESS = allAddresses[`${type}_TK_BOBA`]; + let L0_ETH_ENDPOINT = this.addresses.Layer_Zero_Endpoint; + let L0_TARGET_CHAIN_ID = this.addresses.layerZeroTargetChainID; + let ETH_L1_BOBA_ADDRESS = this.addresses.TK_L1BOBA; + let PROXY_ETH_L1_BRIDGE_ADDRESS_TO = this.addresses[`Proxy__EthBridgeTo${type}`]; + let ALT_L1_BOBA_ADDRESS = this.addresses[`${type}_TK_BOBA`]; /* proxy eth bridge contract */ const Proxy__EthBridge = new ethers.Contract( PROXY_ETH_L1_BRIDGE_ADDRESS_TO, @@ -4916,6 +4668,8 @@ class NetworkService { console.log(`🆙 Depositing ${value} 👉 ${type} l1 with 💵 FEE ${ethers.utils.formatEther(estimatedFee._nativeFee)}`); + // TODO: FIXME: Update this function to `withdraw` in case of other deployment than ETHEREUM. + // INPUT STEP MULTICHAIN await Proxy__EthBridge.depositERC20( ETH_L1_BOBA_ADDRESS, ALT_L1_BOBA_ADDRESS, @@ -4950,7 +4704,7 @@ class NetworkService { try { const baseVoter = new ethers.Contract( - allAddresses.BASE_V1_VOTER, + this.addresses.BASE_V1_VOTER, voterJson.abi, this.provider ) @@ -4978,7 +4732,7 @@ class NetworkService { try { const baseVoter = new ethers.Contract( - allAddresses.BASE_V1_VOTER, + this.addresses.BASE_V1_VOTER, voterJson.abi, this.provider.getSigner() ) @@ -5002,7 +4756,7 @@ class NetworkService { const pools = [] const baseVoter = new ethers.Contract( - allAddresses.BASE_V1_VOTER, + this.addresses.BASE_V1_VOTER, voterJson.abi, this.provider ) @@ -5072,10 +4826,9 @@ class NetworkService { if (!this.delegateContract) return - const delegateCheck = await this.delegateContract.attach(allAddresses.GovernorBravoDelegator) + const delegateCheck = await this.delegateContract.attach(this.addresses.GovernorBravoDelegator) try { - let proposalList = [] const proposalCounts = await delegateCheck.proposalCount() @@ -5156,7 +4909,7 @@ class NetworkService { try { const delegateCheck = await this.delegateContract .connect(this.provider.getSigner()) - .attach(allAddresses.GovernorBravoDelegator) + .attach(this.addresses.GovernorBravoDelegator) return delegateCheck.castVote(id, userVote) } catch(error) { console.log("NS: castProposalVote error:",error) diff --git a/packages/boba/gateway/src/services/transaction.service.js b/packages/boba/gateway/src/services/transaction.service.js new file mode 100644 index 0000000000..5c24b64761 --- /dev/null +++ b/packages/boba/gateway/src/services/transaction.service.js @@ -0,0 +1,97 @@ +import omgxWatcherAxiosInstance from "api/omgxWatcherAxios"; +import networkService from "./networkService"; + + +class TransactionService { + + // fetch L2 transactions from omgxWatcherAxiosInstance + async fetchL2Tx() { + let L2Txs = []; + try { + const responseL2 = await omgxWatcherAxiosInstance(networkService.networkConfig) + .post('get.l2.transactions', { + address: networkService.account, + fromRange: 0, + toRange: 1000, + }).catch((error) => { console.log('get l2 tx', error) }) + + if (responseL2.status === 201) { + L2Txs = responseL2.data.map(v => ({ ...v, chain: 'L2' })) + } + return L2Txs + } catch (error) { + console.log('TS: fetchL2Tx',error) + return L2Txs + } + } + + // fetch L0 transactions from omgxWatcherAxiosInstance + async fetchL0Tx() { + let L0Txs = []; + try { + const responseL0 = await omgxWatcherAxiosInstance(networkService.networkConfig) + .post('get.layerzero.transactions', { + address: networkService.account, + fromRange: 0, + toRange: 1000, + }) + + if (responseL0.status === 201) { + L0Txs = responseL0.data.map((v) => ({ + ...v, + hash: v.tx_hash, + blockNumber: parseInt(v.block_number), + timeStamp: parseInt(v.timestamp), //fix bug - sometimes this is string, sometimes an integer + chain: 'L0', + altL1: true, + })) + } + return L0Txs + } catch (error) { + console.log('TS: fetchL0Tx',error) + return L0Txs + } + } + + // fetch L1 pending transactions from omgxWatcherAxiosInstance + async fetchL1PendingTx() { + let txL1pending = []; + try { + const responseL1pending = await omgxWatcherAxiosInstance(networkService.networkConfig) + .post('get.l1.transactions', { + address: networkService.account, + fromRange: 0, + toRange: 1000, + }) + + if (responseL1pending.status === 201) { + //add the chain: 'L1pending' field + txL1pending = responseL1pending.data.map(v => ({ ...v, chain: 'L1pending' })) + }; + return txL1pending + } catch (error) { + console.log('TS: fetchL1PendingTx',error) + return txL1pending + } + } + + /** + * @getTransactions + * - loads L1Txs, l2Txs, l0Txs, L1PendingTxs + * + */ + async getTransactions() { + const result = await Promise.all([ + this.fetchL2Tx(), + this.fetchL0Tx(), + this.fetchL1PendingTx() + ]) + return result.reduce((acc, res) => [ ...acc, ...res ], []) + } + +}; + + +const transctionService = new TransactionService(); + +export default transctionService; diff --git a/packages/boba/gateway/src/services/verifier.service.js b/packages/boba/gateway/src/services/verifier.service.js new file mode 100644 index 0000000000..fc9d2e7499 --- /dev/null +++ b/packages/boba/gateway/src/services/verifier.service.js @@ -0,0 +1,31 @@ + + +import verifierWatcherAxiosInstance from "api/verifierWatcherAxios"; +import networkService from "./networkService"; + + +class VerifierService { + + /** + * @getVerifierStatus + */ + + async getVerifierStatus() { + const response = await verifierWatcherAxiosInstance( + networkService.networkConfig + ).post('/', { jsonrpc: "2.0", method: "status", id: 1 }) + + if (response.status === 200) { + const status = response.data.result + return status + } else { + console.log("VS: Bad verifier response") + return false + } + } + +} + +const verifierService = new VerifierService(); + +export default verifierService; diff --git a/packages/boba/gateway/src/services/wallet.service.js b/packages/boba/gateway/src/services/wallet.service.js new file mode 100644 index 0000000000..556e783318 --- /dev/null +++ b/packages/boba/gateway/src/services/wallet.service.js @@ -0,0 +1,72 @@ +/* eslint-disable quotes */ +/* +Copyright 2021-present Boba Network. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +import { providers } from "ethers" + +class WalletService { + constructor() { + this.provider = null + this.account = null + } + + async connectWallet() { + try { + await window.ethereum.request({ method: 'eth_requestAccounts' }) + this.provider = new providers.Web3Provider(window.ethereum) + this.account = await this.provider.getSigner().getAddress() + } catch (e) { + console.log(`Error connecting wallet: ${e}`) + } + } + + async disconnectWallet() { + try { + await window.ethereum.request({ method: "eth_requestAccounts", params: [{ eth_accounts: {} }] }) + this.provider = null + this.account = null + } catch (e) { + console.log(`Error disconnecting wallet: ${e}`) + } + } + + async switchChain(chainId, chainInfo) { + try { + await window.ethereum.request({ + method: "wallet_switchEthereumChain", + params: [{ chainId }], + }) + } catch (error) { + if (error.code === 4902) { + try { + await window.ethereum.request({ + method: "wallet_addEthereumChain", + params: [chainInfo, this.account], + }) + } catch (addError) { + console.log(`Error adding chain: ${addError}`) + throw new Error(addError.code) + } + } else { + console.log(`Error switching chain: ${error}`) + throw new Error(error.code) + } + } + } +} + +const walletService = new WalletService(); + +export default walletService; diff --git a/packages/boba/gateway/src/store/index.js b/packages/boba/gateway/src/store/index.js index 8b05a638e8..83303ad9d2 100644 --- a/packages/boba/gateway/src/store/index.js +++ b/packages/boba/gateway/src/store/index.js @@ -14,15 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */ import { createStore , applyMiddleware } from 'redux' -import reducers from 'reducers' +import RootReducer from 'reducers' import reduxThunk from 'redux-thunk' +import persistReducer from 'redux-persist/lib/persistReducer' +import storage from 'redux-persist/lib/storage' +import persistStore from 'redux-persist/lib/persistStore' const initialState = {} -const store = createStore( - reducers, +const persistConfig = { + key: 'root', + storage, + whitelist: ['network'] +} + +const persistedReducer = persistReducer(persistConfig, RootReducer) + +export const store = createStore( + persistedReducer, initialState, applyMiddleware(reduxThunk) ) -export default store +export default store; + +export const persistor = persistStore(store) diff --git a/packages/boba/gateway/src/util/amountConvert.js b/packages/boba/gateway/src/util/amountConvert.js index 25687fe705..a0498290a0 100644 --- a/packages/boba/gateway/src/util/amountConvert.js +++ b/packages/boba/gateway/src/util/amountConvert.js @@ -16,17 +16,17 @@ limitations under the License. */ // we use BigNumber here for decimal support import BigNumber from 'bignumber.js'; -export function logAmount (amount, power, truncate = 0) { +export function logAmount(amount, power, truncate = 0) { const x = new BigNumber(amount); const exp = new BigNumber(10).pow(power); const calculated = x.div(exp); - if(truncate > 0) - return calculated.toFixed(truncate); + if (truncate > 0) + return calculated.toFixed(truncate); else - return calculated.toFixed(); + return calculated.toFixed(); } /*Takes a value such as 3.92 and converts it into @@ -37,7 +37,7 @@ Duplicates ethers.utils.parseUnits( valueString , decimalsOrUnitName ) => BigNumber */ -export function powAmount (amount, decimals) { +export function powAmount(amount, decimals) { const x = new BigNumber(amount) const exp = new BigNumber(10).pow(decimals) @@ -57,18 +57,26 @@ export function toWei_String(amount, decimals) { } export function amountToUsd(amount, lookupPrice, token) { - if (token.symbol === 'ETH' && !!lookupPrice['ethereum']) { - return amount * lookupPrice['ethereum'].usd + if (token.symbol === 'ETH' && !!lookupPrice[ 'ethereum' ]) { + return amount * lookupPrice[ 'ethereum' ].usd } else if (token.symbol === 'BOBA' && !!lookupPrice[ 'boba-network' ]) { - return amount * lookupPrice['boba-network'].usd + return amount * lookupPrice[ 'boba-network' ].usd } else if (token.symbol === 'OLO' && !!lookupPrice[ 'oolongswap' ]) { - return amount * lookupPrice['oolongswap'].usd + return amount * lookupPrice[ 'oolongswap' ].usd } else if (token.symbol === 'OMG' && !!lookupPrice[ 'omisego' ]) { - return amount * lookupPrice['omisego'].usd + return amount * lookupPrice[ 'omisego' ].usd } else if (token.symbol === 'USDC' && !!lookupPrice[ 'usd-coin' ]) { - return amount * lookupPrice['usd-coin'].usd + return amount * lookupPrice[ 'usd-coin' ].usd + } else if (token.symbol === 'AVAX' && !!lookupPrice[ 'avalanche-2' ]) { + return amount * lookupPrice[ 'avalanche-2' ].usd + } else if (token.symbol === 'FTM' && !!lookupPrice[ 'fantom' ]) { + return amount * lookupPrice[ 'fantom' ].usd + } else if ([ 'BNB', 'tBNB' ].includes(token.symbol) && !!lookupPrice[ 'binancecoin' ]) { + return amount * lookupPrice[ 'binancecoin' ].usd + } else if ([ 'DEV', 'GLMR' ].includes(token.symbol) && !!lookupPrice[ 'moonbeam' ]) { + return amount * lookupPrice[ 'moonbeam' ].usd } else if (!!lookupPrice[ token.symbol.toLowerCase() ]) { - return amount * lookupPrice[token.symbol.toLowerCase()].usd + return amount * lookupPrice[ token.symbol.toLowerCase() ].usd } else { return 0 } diff --git a/packages/boba/gateway/src/util/coinImage.js b/packages/boba/gateway/src/util/coinImage.js index 6de701919c..548fcb1c5f 100644 --- a/packages/boba/gateway/src/util/coinImage.js +++ b/packages/boba/gateway/src/util/coinImage.js @@ -31,7 +31,9 @@ import wagmiv2OLOLogo from 'images/wagmiv2olo.png' import oloLogo from 'images/olo.svg' import CGTLogo from 'images/CGT.svg' import avaxLog from 'images/avax.svg' -import glmrLog from 'images/glmr.svg' +import moonbase from 'images/moonbase.png' +import glmrLogo from 'images/glmr.svg' +import mttLogo from 'images/mtt.png' export const getCoinImage = (symbol) => { @@ -104,6 +106,9 @@ export const getCoinImage = (symbol) => { case "BNB": logo = bnbLogo; break; + case "tBNB": + logo = bnbLogo; + break; case "FTM": logo = ftmLogo; break; @@ -144,7 +149,13 @@ export const getCoinImage = (symbol) => { logo = avaxLog; break; case "GLMR": - logo = glmrLog; + logo = glmrLogo; + break; + case "DEV": + logo = moonbase; + break; + case "MTT": + logo = mttLogo; break; default: logo = ethLogo; diff --git a/packages/boba/gateway/src/util/constant.js b/packages/boba/gateway/src/util/constant.js index 6694c555d8..02f51fb942 100644 --- a/packages/boba/gateway/src/util/constant.js +++ b/packages/boba/gateway/src/util/constant.js @@ -10,15 +10,12 @@ export const POLL_INTERVAL = process.env.REACT_APP_POLL_INTERVAL || 20000 export const GAS_POLL_INTERVAL = process.env.REACT_APP_GAS_POLL_INTERVAL || 40000 export const GA4_MEASUREMENT_ID = process.env.REACT_APP_GA4_MEASUREMENT_ID || null export const APP_ENV = process.env.REACT_APP_ENV || 'dev' -export const APP_CHAIN = process.env.REACT_APP_CHAIN export const SENTRY_DSN = process.env.REACT_APP_SENTRY_DSN || null export const APP_ZENDESK_KEY = process.env.REACT_APP_ZENDESK_KEY || null export const INFURA_ID = process.env.REACT_APP_INFURA_ID export const MAX_HEALTH_BLOCK_LAG = process.env.REACT_APP_MAX_HEALTH_BLOCK_LAG export const WALLET_VERSION = process.env.REACT_APP_WALLET_VERSION export const APP_STATUS = process.env.REACT_APP_STATUS || 'normal' -export const SELLER_OPTIMISM_API_URL = process.env.REACT_APP_SELLER_OPTIMISM_API_URL -export const SERVICE_OPTIMISM_API_URL = process.env.REACT_APP_SERVICE_OPTIMISM_API_URL export const SPEED_CHECK = process.env.REACT_APP_SPEED_CHECK export const TARGET_CHAIN_URL = process.env.REACT_APP_TARGET_CHAIN_URL // VE DAO FLAG @@ -73,3 +70,33 @@ export const ROUTES_PATH = { DEV_TOOLS: '/devtools', } export const PER_PAGE = 8 + +export const PAGES_BY_NETWORK = { + ethereum: ['Bridge', 'Ecosystem', 'Wallet', 'History', 'Earn', 'Stake', 'LinksToBobaChains', 'DAO', 'Monster'], + bnb: ['Wallet', 'Earn', 'History', 'LinksToBobaChains' ], + avax: ['Wallet', 'Earn', 'History', 'LinksToBobaChains' ], + fantom: ['Wallet', 'Earn', 'History', 'LinksToBobaChains' ], + moonbeam: ['Wallet', 'Earn', 'History', 'LinksToBobaChains' ], +} + +export const LAYER = { + L1: 'L1', + L2: 'L2', +} + + +export const DEFAULT_NETWORK = { + NAME: { + L1: 'Ethereum', + L2: 'Boba' + }, + ICON: { + L1: 'ethereum', + L2: 'boba' + } +} + + +export const MM_EXTENTION_URL = 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en' + +export const MIN_NATIVE_L1_BALANCE = 0.002 diff --git a/packages/boba/gateway/src/util/masterConfig.js b/packages/boba/gateway/src/util/masterConfig.js index b83546573b..661c8dc52f 100644 --- a/packages/boba/gateway/src/util/masterConfig.js +++ b/packages/boba/gateway/src/util/masterConfig.js @@ -1,12 +1,9 @@ /* Copyright 2021-present Boba Network. - Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,126 +11,11 @@ See the License for the specific language governing permissions and limitations under the License. */ import { - APP_CHAIN, INFURA_ID, MAX_HEALTH_BLOCK_LAG, + MAX_HEALTH_BLOCK_LAG, } from './constant' -let NETWORK - -if (APP_CHAIN === 'goerli') { - NETWORK = { - goerli: { - OMGX_WATCHER_URL: `https://api-watcher.goerli.boba.network/`, - VERIFIER_WATCHER_URL: `https://api-verifier.goerli.boba.network/`, - MM_Label: `Goerli`, - addressManager: `0x6FF9c8FF8F0B6a0763a3030540c21aFC721A9148`, - L1: { - name: "Goerli", - chainId: 5, - chainIdHex: '0x5', - rpcUrl: `https://goerli.infura.io/v3/${INFURA_ID}`, - transaction: `https://goerli.etherscan.io/tx/` - }, - L2: { - name: "BOBA Goerli L2", - chainId: 2888, - chainIdHex: '0xB48', - rpcUrl: `https://goerli.boba.network`, - blockExplorer: `https://testnet.bobascan.com/`, - transaction: `https://testnet.bobascan.com/tx/` - }, - ALTL1: { - name: "Alt L1s", - // chainId: 28, - // chainIdHex: '0x1C', - rpcUrl: ``, - // blockExplorer: `https://testnet.bobascan.com/`, - // transaction: `https://testnet.bobascan.com/tx/` - }, - payloadForL1SecurityFee: { - from: '0x122816e7A7AeB40601d0aC0DCAA8402F7aa4cDfA', - to: '0x4df04E20cCd9a8B82634754fcB041e86c5FF085A', - value: '0x174876e800', - data: - '0x7ff36ab500000000000000000000000000000000000000000000000003939808cc6852cc0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000122816e7a7aeb40601d0ac0dcaa8402f7aa4cdfa0000000000000000000000000000000000000000000000000000008c14b4a17a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead00000000000000000000000000004204a0af0991b2066d2d617854d5995714a79132', - }, - payloadForFastDepositBatchCost: { - from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', - to: '0x12F8d1cD442cf1CF94417cE6309c6D2461Bd91a3', - value: '0x038d7ea4c68000', - data: - '0xa44c80e3000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006a6676813d3d4317442cf84667425c13553f4a760000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000' - }, - gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2` - } - } -} else if (APP_CHAIN === 'mainnet') { - NETWORK = { - mainnet: { - OMGX_WATCHER_URL: `https://api-watcher.mainnet.boba.network/`, - VERIFIER_WATCHER_URL: `https://api-verifier.mainnet.boba.network/`, - MM_Label: `Mainnet`, - addressManager: `0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089`, - L1: { - name: "Mainnet", - chainId: 1, - chainIdHex: '0x1', - rpcUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`, - transaction: ` https://etherscan.io/tx/`, - }, - L2: { - name: "BOBA L2", - chainId: 288, - chainIdHex: '0x120', - rpcUrl: `https://mainnet.boba.network`, - blockExplorer: `https://bobascan.com/`, - transaction: `https://bobascan.com/tx/`, - }, - payloadForL1SecurityFee: { - from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', - to: '0x17C83E2B96ACfb5190d63F5E46d93c107eC0b514', - value: '0x38d7ea4c68000', - data: - '0x7ff36ab5000000000000000000000000000000000000000000000000132cc41aecbfbace00000000000000000000000000000000000000000000000000000000000000800000000000000000000000005e7a06025892d8eef0b5fa263fa0d4d2e5c3b54900000000000000000000000000000000000000000000000000000001c73d14500000000000000000000000000000000000000000000000000000000000000002000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead00000000000000000000000000005008f837883ea9a07271a1b5eb0658404f5a9610', - }, - payloadForFastDepositBatchCost: { - from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', - to: '0x1A26ef6575B7BBB864d984D9255C069F6c361a14', - value: '0x038d7ea4c68000', - data: - '0xa44c80e30000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000042bbfa2e77757c645eeaad1655e0911a7553efbc0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000' - }, - gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2` - } - } -} else if (APP_CHAIN === 'local') { - NETWORK = { - local: { - OMGX_WATCHER_URL: null, //Does not exist on local - MM_Label: `Local`, - addressManager: `0x5FbDB2315678afecb367f032d93F642f64180aa3`, - L1: { - name: "Local L1", - chainId: 31337, - chainIdHex: '0x7A69', - rpcUrl: `http://${window.location.hostname}:9545`, - }, - L2: { - name: "Local L2", - chainId: 31338, - chainIdHex: '0x7A6A', - rpcUrl: `http://${window.location.hostname}:8545`, - blockExplorer: null, //does not exist on local - }, - } - } -} - const BaseServices = { WALLET_SERVICE: `https://api-service.boba.network/`, - //relevant to local? - SERVICE_OPTIMISM_API_URL: `https://zlba6djrv6.execute-api.us-west-1.amazonaws.com/prod/`, - //relevant to local? - WEBSOCKET_API_URL: `wss://d1cj5xnal2.execute-api.us-west-1.amazonaws.com/prod`, //Coing gecko url COIN_GECKO_URL: `https://api.coingecko.com/api/v3/`, //ETH gas station @@ -144,10 +26,6 @@ const BaseServices = { GOERLI_META_TRANSACTION: `https://api-meta-transaction.goerli.boba.network/`, } -export function getNetwork() { - return NETWORK -} - export function getBaseServices() { return BaseServices } diff --git a/packages/boba/gateway/src/util/network/config/avax.js b/packages/boba/gateway/src/util/network/config/avax.js new file mode 100644 index 0000000000..5b9dbfacf4 --- /dev/null +++ b/packages/boba/gateway/src/util/network/config/avax.js @@ -0,0 +1,68 @@ + +export const avaxConfig = { + Testnet: { + OMGX_WATCHER_URL: `https://api-watcher.testnet.avax.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.testnet.avax.boba.network/`, + MM_Label: `Boba Avalanche Testnet`, + addressManager: `0xcE78de95b85212BC348452e91e0e74c17cf37c79`, + L1: { + name: "Avalanche Testnet", + chainId: 43113, + chainIdHex: '0xA869', + rpcUrl: [ + `https://api.avax-test.network/ext/bc/C/rpc`, + `https://rpc.ankr.com/avalanche_fuji`, + ], + transaction: `https://testnet.snowtrace.io/tx/`, + blockExplorerUrl: `https://testnet.snowtrace.io/`, + symbol: "AVAX", + tokenName: "AVAX", + }, + L2: { + name: "Boba Avalanche Testnet", + chainId: 4328, + chainIdHex: '0x10E8', + rpcUrl: `https://testnet.avax.boba.network`, + blockExplorer: `https://blockexplorer.testnet.avax.boba.network/`, + transaction: `https://blockexplorer.testnet.avax.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.testnet.avax.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20Avalanche%20Testnet%20for%20Avalanche%20` + }, + Mainnet: { + OMGX_WATCHER_URL: `https://api-watcher.avax.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.avax.boba.network/`, + MM_Label: `Boba Avalanche Mainnet`, + addressManager: `0x00220f8ce1c4be8436574e575fE38558d85e2E6b`, + L1: { + name: "Avalanche Mainnet", + chainId: 43114, + chainIdHex: '0xA86A', + rpcUrl: [ + `https://api.avax.network/ext/bc/C/rpc`, + `https://rpc.ankr.com/avalanche`, + `https://1rpc.io/avax/c`, + ], + transaction: `https://snowtrace.io/tx/`, + blockExplorerUrl: `https://snowtrace.io/`, + symbol: "AVAX", + tokenName: "AVAX", + }, + L2: { + name: "Boba Avalanche Mainnet", + chainId: 43288, + chainIdHex: '0xA918', + rpcUrl: `https://avax.boba.network`, + blockExplorer: `https://blockexplorer.avax.boba.network/`, + transaction: `https://blockexplorer.avax.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.avax.boba.network`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20Avalanche%20Testnet%20for%20Avalanche%20` + } +} diff --git a/packages/boba/gateway/src/util/network/config/bnb.js b/packages/boba/gateway/src/util/network/config/bnb.js new file mode 100644 index 0000000000..9697fc9705 --- /dev/null +++ b/packages/boba/gateway/src/util/network/config/bnb.js @@ -0,0 +1,69 @@ + +export const bnbConfig = { + Testnet: { + OMGX_WATCHER_URL: `https://api-watcher.testnet.bnb.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.testnet.bnb.boba.network/`, + MM_Label: `bobaBnbTestnet`, + addressManager: `0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa`, + L1: { + name: "BNB Testnet", + chainId: 97, + chainIdHex: '0x61', + rpcUrl: [ + `https://data-seed-prebsc-1-s1.binance.org:8545`, + `https://data-seed-prebsc-2-s1.binance.org:8545`, + `https://bsc-testnet.public.blastapi.io`, + ], + transaction: `https://testnet.bscscan.com/tx/`, + blockExplorerUrl: `https://testnet.bscscan.com/`, + symbol: "tBNB", + tokenName: "tBNB", + }, + L2: { + name: "Boba BNB Testnet", + chainId: 9728, + chainIdHex: '0x2600', + rpcUrl: `https://testnet.bnb.boba.network`, + blockExplorer: `https://blockexplorer.testnet.bnb.boba.network/`, + transaction: `https://blockexplorer.testnet.bnb.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.testnet.bnb.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20BNB%20Testnet%20for%20BNB%20` + }, + Mainnet: { + OMGX_WATCHER_URL: `https://api-watcher.bnb.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.bnb.boba.network/`, + MM_Label: `bobaBnb`, + addressManager: `0xeb989B25597259cfa51Bd396cE1d4B085EC4c753`, + L1: { + name: "Binance Smart Chain Mainnet", + chainId: 56, + chainIdHex: '0x38', + rpcUrl: [ + `https://bsc-dataseed.binance.org`, + `https://rpc.ankr.com/bsc`, + `https://1rpc.io/bnb`, + ], + transaction: `https://bscscan.com/tx/`, + blockExplorerUrl: `https://bscscan.com/`, + symbol: "BNB", + tokenName: "BNB", + }, + L2: { + name: "Boba BNB Mainnet", + chainId: 56288, + chainIdHex: '0xDBE0', + rpcUrl: `https://bnb.boba.network`, + blockExplorer: `https://blockexplorer.bnb.boba.network/`, + transaction: `https://blockexplorer.bnb.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.bnb.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20BNB%20Testnet%20for%20BNB%20` + } +} diff --git a/packages/boba/gateway/src/util/network/config/ethereum.js b/packages/boba/gateway/src/util/network/config/ethereum.js new file mode 100644 index 0000000000..adc51029a6 --- /dev/null +++ b/packages/boba/gateway/src/util/network/config/ethereum.js @@ -0,0 +1,99 @@ +import {INFURA_ID } from "util/constant"; + +export const ethereumConfig = { + Testnet: { + OMGX_WATCHER_URL: `https://api-watcher.goerli.boba.network/`, + VERIFIER_WATCHER_URL: `https://api-verifier.goerli.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.goerli.boba.network/`, + MM_Label: `Goerli`, + addressManager: `0x6FF9c8FF8F0B6a0763a3030540c21aFC721A9148`, + L1: { + name: "Goerli", + chainId: 5, + chainIdHex: '0x5', + rpcUrl: [ + `https://goerli.infura.io/v3/${INFURA_ID}`, + `https://rpc.ankr.com/eth_goerli`, + ], + transaction: `https://goerli.etherscan.io/tx/`, + blockExplorerUrl: `https://goerli.etherscan.io/`, + symbol: 'ETH', + tokenName: 'ETH', + }, + L2: { + name: "BOBA Goerli L2", + chainId: 2888, + chainIdHex: '0xB48', + rpcUrl: `https://goerli.boba.network`, + blockExplorer: `https://testnet.bobascan.com/`, + transaction: `https://testnet.bobascan.com/tx/`, + blockExplorerUrl: `https://testnet.bobascan.com/`, + symbol: 'ETH', + tokenName: 'ETH', + }, + payloadForL1SecurityFee: { + from: '0x122816e7A7AeB40601d0aC0DCAA8402F7aa4cDfA', + to: '0x4df04E20cCd9a8B82634754fcB041e86c5FF085A', + value: '0x174876e800', + data: + '0x7ff36ab500000000000000000000000000000000000000000000000003939808cc6852cc0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000122816e7a7aeb40601d0ac0dcaa8402f7aa4cdfa0000000000000000000000000000000000000000000000000000008c14b4a17a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead00000000000000000000000000004204a0af0991b2066d2d617854d5995714a79132', + }, + payloadForFastDepositBatchCost: { + from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', + to: '0x12F8d1cD442cf1CF94417cE6309c6D2461Bd91a3', + value: '0x038d7ea4c68000', + data: + '0xa44c80e3000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000006a6676813d3d4317442cf84667425c13553f4a760000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000' + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: "https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20Network%20" + }, + Mainnet: { + OMGX_WATCHER_URL: `https://api-watcher.mainnet.boba.network/`, + VERIFIER_WATCHER_URL: `https://api-verifier.mainnet.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.mainnet.boba.network/`, + MM_Label: `Mainnet`, + addressManager: `0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089`, + L1: { + name: "Mainnet", + chainId: 1, + chainIdHex: '0x1', + rpcUrl: [ + `https://mainnet.infura.io/v3/${INFURA_ID}`, + `https://rpc.ankr.com/eth`, + `https://cloudflare-eth.com`, + ], + transaction: ` https://etherscan.io/tx/`, + blockExplorerUrl: `https://etherscan.io/`, + symbol: 'ETH', + tokenName: 'ETH', + }, + L2: { + name: "BOBA L2", + chainId: 288, + chainIdHex: '0x120', + rpcUrl: `https://mainnet.boba.network`, + blockExplorer: `https://bobascan.com/`, + transaction: `https://bobascan.com/tx/`, + blockExplorerUrl: `https://bobascan.com/`, + symbol: 'ETH', + tokenName: 'ETH', + }, + payloadForL1SecurityFee: { + from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', + to: '0x17C83E2B96ACfb5190d63F5E46d93c107eC0b514', + value: '0x38d7ea4c68000', + data: + '0x7ff36ab5000000000000000000000000000000000000000000000000132cc41aecbfbace00000000000000000000000000000000000000000000000000000000000000800000000000000000000000005e7a06025892d8eef0b5fa263fa0d4d2e5c3b54900000000000000000000000000000000000000000000000000000001c73d14500000000000000000000000000000000000000000000000000000000000000002000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead00000000000000000000000000005008f837883ea9a07271a1b5eb0658404f5a9610', + }, + payloadForFastDepositBatchCost: { + from: '0x5E7a06025892d8Eef0b5fa263fA0d4d2E5C3B549', + to: '0x1A26ef6575B7BBB864d984D9255C069F6c361a14', + value: '0x038d7ea4c68000', + data: + '0xa44c80e30000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000042bbfa2e77757c645eeaad1655e0911a7553efbc0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000038d7ea4c68000' + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: "https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Boba%20Network%20" + } +} diff --git a/packages/boba/gateway/src/util/network/config/fantom.js b/packages/boba/gateway/src/util/network/config/fantom.js new file mode 100644 index 0000000000..1801c181a7 --- /dev/null +++ b/packages/boba/gateway/src/util/network/config/fantom.js @@ -0,0 +1,69 @@ + +export const fantomConfig = { + Testnet: { + OMGX_WATCHER_URL: `https://api-watcher.testnet.bobaopera.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.testnet.bobaopera.boba.network/`, + MM_Label: `bobaOperaTestnet`, + addressManager: `0x12ad9f501149D3FDd703cC10c567F416B7F0af8b`, + L1: { + name: "Fantom Testnet", + chainId: 4002, + chainIdHex: '0xFA2', + rpcUrl: [ + `https://rpc.testnet.fantom.network`, + `https://rpc.ankr.com/fantom_testnet`, + `https://fantom-testnet.public.blastapi.io`, + ], + transaction: `https://testnet.ftmscan.com/tx/`, + blockExplorerUrl: `https://testnet.ftmscan.com/`, + symbol: 'FTM', + tokenName: 'FTM', + }, + L2: { + name: "BobaOpera Testnet", + chainId: 4051, + chainIdHex: '0xFD3', + rpcUrl: `https://testnet.bobaopera.boba.network`, + blockExplorer: `https://blockexplorer.testnet.bobaopera.boba.network/`, + transaction: `https://blockexplorer.testnet.bobaopera.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.testnet.bobaopera.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Bobaopera%20Testnet%20for%20Fantom%20` + }, + Mainnet: { + OMGX_WATCHER_URL: `https://api-watcher.bobaopera.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.bobaopera.boba.network/`, + MM_Label: `Bobaopera`, + addressManager: `0x4e7325bcf09e091Bb8119258B885D4ef687B7386`, + L1: { + name: "Fantom Mainnet", + chainId: 250, + chainIdHex: '0xFA', + rpcUrl: [ + `https://rpc.fantom.network`, + `https://rpc.ankr.com/fantom`, + `https://1rpc.io/ftm`, + ], + transaction: `https://ftmscan.com/tx/`, + blockExplorerUrl: `https://ftmscan.com/`, + symbol: 'FTM', + tokenName: 'FTM', + }, + L2: { + name: "Bobaopera Mainnet", + chainId: 301, + chainIdHex: '0x12D', + rpcUrl: `https://bobaopera.boba.network`, + blockExplorer: `https://blockexplorer.bobaopera.boba.network/`, + transaction: `https://blockexplorer.bobaopera.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.bobaopera.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Bobaopera%20Testnet%20for%20Fantom%20` + } +} diff --git a/packages/boba/gateway/src/util/network/config/local.js b/packages/boba/gateway/src/util/network/config/local.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/boba/gateway/src/util/network/config/moonbeam.js b/packages/boba/gateway/src/util/network/config/moonbeam.js new file mode 100644 index 0000000000..78d2265b06 --- /dev/null +++ b/packages/boba/gateway/src/util/network/config/moonbeam.js @@ -0,0 +1,68 @@ +export const moonbeamConfig = { + Testnet: { + OMGX_WATCHER_URL: `https://api-watcher.bobabase.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.bobabase.boba.network/`, + MM_Label: `BobaBase`, + addressManager: `0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B`, + L1: { + name: "MoonBase", + chainId: 1287, + chainIdHex: '0x507', + rpcUrl: [ + `https://rpc.api.moonbase.moonbeam.network`, + `https://moonbase-alpha.public.blastapi.io`, + `https://moonbeam-alpha.api.onfinality.io/public`, + ], + transaction: `https://moonbase.moonscan.io/tx/`, + blockExplorerUrl: `https://moonbase.moonscan.io`, + symbol: 'DEV', + tokenName: 'DEV', + }, + L2: { + name: "BobaBase", + chainId: 1297, + chainIdHex: '0x511', + rpcUrl: `https://bobabase.boba.network`, + blockExplorer: `https://blockexplorer.bobabase.boba.network/`, + transaction: `https://blockexplorer.bobabase.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.bobabase.boba.network`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Bobabase%20for%20Moonbeam%20` + }, + Mainnet: { + OMGX_WATCHER_URL: `https://api-watcher.bobabeam.boba.network/`, + META_TRANSACTION: `https://api-meta-transaction.bobabeam.boba.network/`, + MM_Label: `bobaBeam`, + addressManager: `0x564c10A60af35a07f0EA8Be3106a4D81014b21a0`, + L1: { + name: "MoonBeam", + chainId: 1284, + chainIdHex: '0x504', + rpcUrl: [ + `https://rpc.api.moonbeam.network`, + `https://rpc.ankr.com/moonbeam`, + `https://1rpc.io/glmr`, + ], + transaction: `https://moonscan.io/tx/`, + blockExplorerUrl: `https://moonscan.io/`, + symbol: "GLMR", + tokenName: "GLMR", + }, + L2: { + name: "BobaBeam", + chainId: 1294, + chainIdHex: '0x50E', + rpcUrl: `https://bobabeam.boba.network`, + blockExplorer: `https://blockexplorer.bobabeam.boba.network/`, + transaction: `https://blockexplorer.bobabeam.boba.network/tx/`, + blockExplorerUrl: `https://blockexplorer.bobabeam.boba.network/`, + symbol: "BOBA", + tokenName: "Boba Token", + }, + gasEstimateAccount: `0xdb5a187FED81c735ddB1F6E47F28f2A5F74639b2`, + twitterFaucetPromotionText: `https://twitter.com/intent/tweet?text=I%27m%20developing%20on%20Bobabeam%20for%20Moonbeam%20` + } +} diff --git a/packages/boba/gateway/src/util/network/network.util.js b/packages/boba/gateway/src/util/network/network.util.js new file mode 100644 index 0000000000..333dc63d3e --- /dev/null +++ b/packages/boba/gateway/src/util/network/network.util.js @@ -0,0 +1,301 @@ +import { providers } from 'ethers'; + +import EthereumIcon from 'components/icons/chain/L1/EthereumIcon'; +import BNBIcon from 'components/icons/chain/L1/BNBIcon'; +import AvalancheIcon from 'components/icons/chain/L1/AvalancheIcon'; +import FantomIcon from 'components/icons/chain/L1/FantomIcon'; +import MoonbeamIcon from 'components/icons/chain/L1/MoonbeamIcon'; +import MoonbaseIcon from 'components/icons/chain/L1/MoonbaseIcon'; + +import BobaIcon from 'components/icons/chain/L2/BobaIcon'; +import BobaBNBIcon from 'components/icons/chain/L2/BobaBNBIcon'; +import BobaAvaxIcon from 'components/icons/chain/L2/BobaAvaxIcon'; +import BobaFantomIcon from 'components/icons/chain/L2/BobaFantomIcon'; +import BobabeamIcon from 'components/icons/chain/L2/BobabeamIcon'; +import BobabaseIcon from 'components/icons/chain/L2/BobabaseIcon'; + +import { ethereumConfig } from './config/ethereum'; +import { bnbConfig } from './config/bnb'; +import { fantomConfig } from './config/fantom'; +import { avaxConfig } from './config/avax'; +import { moonbeamConfig } from './config/moonbeam'; +import { LAYER } from 'util/constant'; + +export const L1_ICONS = { + ethereum: EthereumIcon, + bnb: BNBIcon, + avax: AvalancheIcon, + fantom: FantomIcon, + moonbeam: MoonbeamIcon, + moonbase: MoonbaseIcon, +} + +export const L2_ICONS = { + ethereum: BobaIcon, + bnb: BobaBNBIcon, + avax: BobaAvaxIcon, + fantom: BobaFantomIcon, + moonbeam: BobabeamIcon, + moonbase: BobabaseIcon, +} + + +export const NETWORK_TYPE = { + MAINNET: 'Mainnet', + TESTNET: 'Testnet' +} + +export const NETWORK = { + ETHEREUM: 'ETHEREUM', + BNB: 'BNB', + FANTOM: 'FANTOM', + AVAX: 'AVAX', + MOONBEAM: 'MOONBEAM', +} + + +export const CHAIN_ID_LIST = { + 5: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.ETHEREUM, + layer: LAYER.L1 + }, + 2888: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.ETHEREUM, + layer: LAYER.L2 + }, + 1: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.ETHEREUM, + layer: LAYER.L1 + }, + 288: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.ETHEREUM, + layer: LAYER.L2 + }, + 43113: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.AVAX, + layer: LAYER.L1 + }, + 4328: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.AVAX, + layer: LAYER.L2 + }, + 43114: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.AVAX, + layer: LAYER.L1 + }, + 43288: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.AVAX, + layer: LAYER.L2 + }, + 97: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.BNB, + layer: LAYER.L1 + }, + 9728: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.BNB, + layer: LAYER.L2 + }, + 56: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.BNB, + layer: LAYER.L1 + }, + 56288: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.BNB, + layer: LAYER.L2 + }, + 4002: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.FANTOM, + layer: LAYER.L1 + }, + 4051: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.FANTOM, + layer: LAYER.L2 + }, + 250: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.FANTOM, + layer: LAYER.L1 + }, + 301: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.FANTOM, + layer: LAYER.L2 + }, + 1287: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.MOONBEAM, + layer: LAYER.L1 + }, + 1297: { + networkType: NETWORK_TYPE.TESTNET, + chain: NETWORK.MOONBEAM, + layer: LAYER.L2 + }, + 1284: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.MOONBEAM, + layer: LAYER.L1 + }, + 1294: { + networkType: NETWORK_TYPE.MAINNET, + chain: NETWORK.MOONBEAM, + layer: LAYER.L2 + }, +} + +export const NetworkList = { + Mainnet: [ + { + icon: 'ethereum', + chain: NETWORK.ETHEREUM, + label: 'Ethereum <> Boba', + key: 'ethereum', + name: { + l1: 'Ethereum', + l2: 'Boba' + } + }, + { + icon: 'bnb', + chain: NETWORK.BNB, + label: 'BNB <> Boba', + key: 'bnb', + name: { + l1: 'Binance Smart Chain Mainnet', + l2: 'Boba BNB Mainnet' + } + }, + { + icon: 'avax', + chain: NETWORK.AVAX, + label: 'Avalanche <> Boba', + key: 'avax', + name: { + l1: 'Avalanche Mainnet C-Chain', + l2: 'Boba Avalance Mainnet' + } + }, + { + icon: 'fantom', + chain: NETWORK.FANTOM, + label: 'Fantom <> Boba', + key: 'fantom', + name: { + l1: 'Fantom Mainnet', + l2: 'Bobaopera Mainnet' + } + }, + { + icon: 'moonbeam', + chain: NETWORK.MOONBEAM, + label: 'Moonbeam <> Boba', + key: 'moonbeam', + name: { + l1: 'Moonbeam', + l2: 'Bobabeam' + } + } + ], + Testnet: [ + { + icon: 'ethereum', + chain: NETWORK.ETHEREUM, + label: 'Ethereum (Goerli) <> Boba', + key: 'ethereum', + name: { + l1: 'Ethereum (Goerli)', + l2: 'Boba', + } + }, + { + icon: 'bnb', + chain: NETWORK.BNB, + label: 'BNB (Testnet) <> Boba', + key: 'bnb', + name: { + l1: 'BNB Testnet', + l2: 'Boba BNB Testnet', + } + }, + { + icon: 'avax', + chain: NETWORK.AVAX, + label: 'Fuji (Testnet) <> Boba', + key: 'avax', + name: { + l1: 'Fuji Testnet', + l2: 'Boba Fuji Testnet', + } + }, + { + icon: 'fantom', + chain: NETWORK.FANTOM, + label: 'Opera (Testnet) <> Boba', + key: 'fantom', + name: { + l1: 'Fantom Testnet', + l2: 'Bobaopera Testnet', + } + }, + { + icon: 'moonbase', + chain: NETWORK.MOONBEAM, + label: 'Moonbase <> Boba', + key: 'moonbeam', + name: { + l1: 'Moonbase', + l2: 'Bobabase', + } + }, + ] +} + +const networkConfig = { + [NETWORK.ETHEREUM] : ethereumConfig, + [NETWORK.BNB] : bnbConfig, + [NETWORK.FANTOM] : fantomConfig, + [NETWORK.AVAX] : avaxConfig, + [NETWORK.MOONBEAM] : moonbeamConfig +} + +export const getNetworkDetail = ({ + network, + networkType +}) => { + return networkConfig[network][networkType] +} + +export const getBlockExplorerUrl = ({ + network, + networkType, + layer +}) => { + return networkConfig[network][networkType][layer]?.blockExplorerUrl +} + +export const pingRpcUrl = async ( + rpcUrl, +) => { + const provider = new providers.JsonRpcProvider(rpcUrl) + try { + await provider.getBlockNumber() + return true + } catch (e) { + console.log(`Error pinging Rpc Url: ${rpcUrl}`) + return false + } +} diff --git a/packages/boba/register/addresses/addressBobaAvax_0x00220f8ce1c4be8436574e575fE38558d85e2E6b.json b/packages/boba/register/addresses/addressBobaAvax_0x00220f8ce1c4be8436574e575fE38558d85e2E6b.json new file mode 100644 index 0000000000..fb95653746 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaAvax_0x00220f8ce1c4be8436574e575fE38558d85e2E6b.json @@ -0,0 +1,59 @@ +{ + "BondManager": "0x26c319B7B2cF823365414d082698C8ac90cbBA63", + "CanonicalTransactionChain": "0x1A19A4ce2b3B0A974Df717b6F88c881a69F315e3", + "ChainStorageContainer-CTC-batches": "0x82e4fCEBa2d0ce0B3f394b6Ab13e4b1B2D485b89", + "ChainStorageContainer-CTC-queue": "0x32fa4eC0aeadf5DEC8461b3834e5572Ad782f075", + "ChainStorageContainer-SCC-batches": "0xc4243ecE585B843c7cf92E65617A4211FA580dDb", + "L1MultiMessageRelayer": "0x87e062dE99Ed71aF9b22dDA63e1b6D43333798f8", + "AddressManager": "0x00220f8ce1c4be8436574e575fE38558d85e2E6b", + "OVM_L1CrossDomainMessenger": "0x19FF7f546b66f69e859E07B61444c3d3EF35ABC5", + "Proxy__L1CrossDomainMessenger": "0x0fc742332ae6D447d6619D93985Aa288B81CBb0C", + "Proxy__L1StandardBridge": "0xf188F1e92B2c78956D2859b84684BFD17103e22c", + "StateCommitmentChain": "0x1ef85D873Cf451C8B9a45DbE40b478E991F51210", + "TK_L1BOBA": "0x3cD790449CF7D187a143d4Bd7F4654d4f2403e02", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L2WBOBA9": "0x26c319B7B2cF823365414d082698C8ac90cbBA63", + "TK_L1AVAX": "0x0000000000000000000000000000000000000000", + "TK_L2AVAX": "0x4200000000000000000000000000000000000023", + "TK_L1USDT.e": "0xc7198437980c041c805A1EDcbA50c1Ce5db95118", + "TK_L2USDT.e": "0x4ED96c1dc969d7E2310D9582A68c39556C005912", + "TK_L1USDt": "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7", + "TK_L2USDt": "0xfaA13D82756f1e0e4dec9416b83121db3Fc35199", + "TK_L1USDC": "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E", + "TK_L2USDC": "0x12bb1A120dcF8Cb7152eDAC9f04d176DD7f41F7e", + "TK_L1USDC.e": "0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664", + "TK_L2USDC.e": "0x126969743a6d300bab08F303f104f0f7DBAfbe20", + "TK_L1BUSD.e": "0x19860CCB0A68fd4213aB9D8266F7bBf05A8dDe98", + "TK_L2BUSD.e": "0xb8B0034CFD89925944C07Ac6CcB2834d1774cfb6", + "TK_L1BUSD": "0x9C9e5fD8bbc25984B178FdCE6117Defa39d2db39", + "TK_L2BUSD": "0x87e062dE99Ed71aF9b22dDA63e1b6D43333798f8", + "TK_L1DAI.e": "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70", + "TK_L2DAI.e": "0x69B7d24f0E03Ff21949081C95dA7288fEa5C844D", + "L1CrossDomainMessengerFast": "0x8A3c2536FDae22D168e3ddaE55BF152660D98026", + "Proxy__L1CrossDomainMessengerFast": "0x5b6714b7926e6D7e34154C9AC945B489978fA7E7", + "L2LiquidityPool": "0x40425E72034eCC797cE77628672c5a7081B54470", + "L1LiquidityPool": "0xCa542506782592028796c456380a58E3D5589422", + "Proxy__L1LiquidityPool": "0x1E6D9F4dDD7C52EF8964e81E5a9a137Ee2489b21", + "Proxy__L2LiquidityPool": "0x0B1b1ce732564974233159213D3931C5400D4B3E", + "L2TokenPool": "0xbFC421c109c4A9851bCE258Ae57D2056c2E7F757", + "L1Message": "0xC12AF64d6Ffe4EB5e3421C91A569E6DA5Ee38f8e", + "L2Message": "0x3B57D8d49e73DA0D589f639A2334C1464C75ed8F", + "AtomicSwap": "0xe6663Fa30eaF07f38C60f33C917E70225ee0b846", + "L2ERC721": "0x00220f8ce1c4be8436574e575fE38558d85e2E6b", + "L2ERC721Reg": "0x938dd85B9c695D9a3A147F65f8991fcf5019BA75", + "L1NFTBridge": "0x9898E7b905dD66422cef07504D8CfFd77c453c48", + "L2NFTBridge": "0x70380b943e5f1fBe5dC8C2Ca3EB9E955B3580938", + "Proxy__L1NFTBridge": "0x328eb74673Eaa1D2d90A48E8137b015F1B6Ed35d", + "Proxy__L2NFTBridge": "0x1A0245f23056132fEcC7098bB011C5C303aE0625", + "L1MultiMessageRelayerFast": "0xf9821061774b9693359F582b007A5F1C39d75Ae3", + "DiscretionaryExitFee": "0x4ef8b611e05121d511d930Bf7EBaeE37f87bfC03", + "FeedRegistry": "0xd5984bD8568447e44d922793E3f210f8F960F065", + "BOBAUSD_Aggregator": "0x82e4fCEBa2d0ce0B3f394b6Ab13e4b1B2D485b89", + "BobaBillingContract": "0x8A4cf5504405A96be09c4fAc2F5f96c6BAe6951c", + "Proxy__BobaBillingContract": "0xc4243ecE585B843c7cf92E65617A4211FA580dDb", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressBobaBeam_0x564c10A60af35a07f0EA8Be3106a4D81014b21a0.json b/packages/boba/register/addresses/addressBobaBeam_0x564c10A60af35a07f0EA8Be3106a4D81014b21a0.json new file mode 100644 index 0000000000..dc7cf88f92 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaBeam_0x564c10A60af35a07f0EA8Be3106a4D81014b21a0.json @@ -0,0 +1,47 @@ +{ + "BondManager": "0xcfe333e0e48EC71f1399a76001cf39E0c6A51dA5", + "CanonicalTransactionChain": "0x99C970105cf6EE2e22b563CB86bCA42D05ac7A95", + "ChainStorageContainer-CTC-batches": "0x808fD25dd00D5F8915Ad69326bFD75A6E014f9b3", + "ChainStorageContainer-CTC-queue": "0x1D023D0B9E8aa136241eB8e8827876f51ef49851", + "ChainStorageContainer-SCC-batches": "0x5Ee60822c68CF0966D8Dc53255627216b4ADC30f", + "L1MultiMessageRelayer": "0x3664bC9BA25D0d3911c39d8ae1734b0B5A3495C1", + "AddressManager": "0x564c10A60af35a07f0EA8Be3106a4D81014b21a0", + "OVM_L1CrossDomainMessenger": "0x9182A0AA011f97633d44383F446A5951bDD3f5bf", + "Proxy__L1CrossDomainMessenger": "0x4765f8b50Bbe049045bBA1270dc7A8CDF17165cF", + "Proxy__L1StandardBridge": "0xAf5297f68D48cd2DE37Ee5cbaC0647fbA4132985", + "StateCommitmentChain": "0xAD379B1518f50Fc737536D2Ec2c13E4640e228A8", + "OVM_Sequencer": "0x9a57cd0a2241f3e5074bec89a86db59098d73e6e", + "Deployer": "0xC31ca2482c936d92dd465391B45940e802A86eDc", + "TK_L1BOBA": "0x18D17A9fD652D7d6a59903E23792ab97F832Ed6C", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L2WBOBA9": "0x74686A29ac7C5703bDC4f9C2DA176DcE55d4DbAC", + "TK_L1GLMR": "0x0000000000000000000000000000000000000000", + "TK_L2GLMR": "0x4200000000000000000000000000000000000023", + "L1CrossDomainMessengerFast": "0xFd4892a500303f5Bfe7C78D49a6aB3dddfCccb92", + "Proxy__L1CrossDomainMessengerFast": "0x17d02C3e6cB69225d83d0bADEb0fC09aE735CA3b", + "L2LiquidityPool": "0x079D6565eEE0129fAe337B52C217951f70c58CFa", + "L1LiquidityPool": "0x1c98d96cfcDc4599D5FbB61Aa30301d94fcA8002", + "Proxy__L1LiquidityPool": "0x3fBc139f80a474c9B19A734e9ABb285b6550dF58", + "Proxy__L2LiquidityPool": "0xD7d057F1b1caBB637BFc81F9bf1Fb74f54941E65", + "L2TokenPool": "0x5Ee60822c68CF0966D8Dc53255627216b4ADC30f", + "L1Message": "0x3bdF3E4543eac155dF6d7F0e5cf55a90E468a33b", + "L2Message": "0x99C970105cf6EE2e22b563CB86bCA42D05ac7A95", + "AtomicSwap": "0xAD379B1518f50Fc737536D2Ec2c13E4640e228A8", + "L2ERC721": "0xD5Ad3B843c4dE06762972a6c1d15BD0Ac96E0231", + "L2ERC721Reg": "0xcfe333e0e48EC71f1399a76001cf39E0c6A51dA5", + "L1NFTBridge": "0x65802425d28168e8148B5D13c35e7490Ac52524e", + "L2NFTBridge": "0xFbcc3F48a6Ca8D169f318360E5d9fe00e553F543", + "Proxy__L1NFTBridge": "0x7f61EB6FFe966E8c14AFb8754Bf0825eb6f54bd7", + "Proxy__L2NFTBridge": "0x9182A0AA011f97633d44383F446A5951bDD3f5bf", + "L1MultiMessageRelayerFast": "0xE2EE964E39720f78Cd75BC146Ed078D301981759", + "DiscretionaryExitFee": "0xC828226424E9D9686bddC0fBA91c4e234b3e6F55", + "FeedRegistry": "0xF60bc956315f4E1EA63B925bA4d857CDd95f3532", + "BOBAUSD_Aggregator": "0xAf5297f68D48cd2DE37Ee5cbaC0647fbA4132985", + "BobaBillingContract": "0xf237D39597B41c9E426e1F23a6aC148DC2a9176e", + "Proxy__BobaBillingContract": "0xb210a4BB024196dC8c5f6f407220cA83e65e45FE", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressBobaBnbTestnet_0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa.json b/packages/boba/register/addresses/addressBobaBnbTestnet_0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa.json new file mode 100644 index 0000000000..3bc61607b7 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaBnbTestnet_0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa.json @@ -0,0 +1,41 @@ +{ + "AddressManager": "0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa", + "OVM_L1CrossDomainMessenger": "0x6fA80303E479Ea2d705F4f241Ef162aA2F793e71", + "Proxy__L1CrossDomainMessenger": "0x53aD38aE4a63Fe33a86E011F7AF4d3fDe3daD145", + "Proxy__L1StandardBridge": "0xBf0939120b4F5E3196b9E12cAC291e03dD058e9a", + "TK_L1BOBA": "0x875cD11fDf085e0E11B0EE6b814b6d0b38fA554C", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L1tBNB": "0x0000000000000000000000000000000000000000", + "TK_L2tBNB": "0x4200000000000000000000000000000000000023", + "TK_L1MTT": "0x02Ed46AA41fcb4a6f06a5F2D43A958F1e8c0A4E6", + "TK_L2MTT": "0xb3BE5C928E3ec6b11985753f7B3C43A8bB12Bc03", + "L1CrossDomainMessengerFast": "0xf5a68fC4734a657652717aCC024fAb390274C0E6", + "Proxy__L1CrossDomainMessengerFast": "0xbbD6a271abcC44f6dE284E6051Da76b4fB57458C", + "L2LiquidityPool": "0x8e449c8267cbe89e0615F6ea8FBf885B5755F90D", + "L1LiquidityPool": "0x026fCac45B06395f626c5e6698444B0B51bC7B43", + "Proxy__L1LiquidityPool": "0xed142c7BdA2A3d5b08Eae78C96b37FFe60Fecf80", + "Proxy__L2LiquidityPool": "0xa1786aDDe89d62014CC50bE01d53c16C7A80D460", + "L2TokenPool": "0x14718bB320d6FC2681EF86864732211a9A0928dD", + "L1Message": "0xb743f3A682C846ccC4584bd8bCb434320a769216", + "L2Message": "0x65f291CDfB05bd1D639DF6268F98594fdacDeCa6", + "AtomicSwap": "0x37FB8bB9EA100CA9a0DE822c9923643ef48Cb8EE", + "L2ERC721": "0x81cF4cBEDF5602401178862f0225b93D2deB2E28", + "L2ERC721Reg": "0x6737867ddd04272a79E7207a008f213e336b00e1", + "L1NFTBridge": "0x347cCB98f420E0E7fbeEd4808732b21C1C86db59", + "L2NFTBridge": "0x3de30b620bA8A44423F70c42f9ed973541d11B12", + "Proxy__L1NFTBridge": "0x4c3f621d01c22658F711c70a12662ECDfCA5916A", + "Proxy__L2NFTBridge": "0x6fA80303E479Ea2d705F4f241Ef162aA2F793e71", + "L1MultiMessageRelayerFast": "0x0F01394F5fc19bA1B9F669bA79b76c9EaAe37987", + "DiscretionaryExitFee": "0x587fA2e1d797Ff79Bf86a24E156A559b6551b2B3", + "FeedRegistry": "0xBf0939120b4F5E3196b9E12cAC291e03dD058e9a", + "BOBAUSD_Aggregator": "0xeb92a5d7d92F5Af18DAdf6c6D7f02be55F3ff355", + "BobaBillingContract": "0x72a3d638C4d022abED8A941aE856da28dB2faB7f", + "Proxy__BobaBillingContract": "0xe43Ff19D561EA6DB84Dd2Ec3754027fAFDa79499", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "AuthenticatedFaucet": "0x4Bee9fE15Ff3645A85792607ce4Eee14ab9E9E02", + "WBOBA9": "0xb743f3A682C846ccC4584bd8bCb434320a769216", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressBobaBnb_0xeb989B25597259cfa51Bd396cE1d4B085EC4c753.json b/packages/boba/register/addresses/addressBobaBnb_0xeb989B25597259cfa51Bd396cE1d4B085EC4c753.json new file mode 100644 index 0000000000..146d6ef306 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaBnb_0xeb989B25597259cfa51Bd396cE1d4B085EC4c753.json @@ -0,0 +1,53 @@ +{ + "BondManager": "0xEB6652A4eb6e0d003Fbb3DD76Ae72694175191cd", + "CanonicalTransactionChain": "0xA0E38a8FE293E9e95c6A4a882F396F1c80e9e2e4", + "ChainStorageContainer-CTC-batches": "0xA774C3f4572C5BA93F75D802ea7Dc6F93228e5cc", + "ChainStorageContainer-CTC-queue": "0xA3f58cF4D4843F600A7e95CE1B23322C6A1A9695", + "ChainStorageContainer-SCC-batches": "0x181D33986CFb5229e42ac3b3a09cad39F1011D17", + "L1MultiMessageRelayer": "0x1E633Dcd0d3D349126983D58988051F7c62c543D", + "AddressManager": "0xeb989B25597259cfa51Bd396cE1d4B085EC4c753", + "OVM_L1CrossDomainMessenger": "0x4085c76ca31c8445A57ABc41393d7D57176A505b", + "Proxy__L1CrossDomainMessenger": "0x31338a7D5d123E18a9a71447136B54B6D28241ae", + "Proxy__L1StandardBridge": "0x1E0f7f4b2656b14C161f1caDF3076C02908F9ACC", + "StateCommitmentChain": "0xeF85fA550e6EC5486121313C895EDe1005e2397f", + "TK_L1BOBA": "0xE0DB679377A0F5Ae2BaE485DE475c9e1d8A4607D", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L2WBOBA9": "0xC58aaD327D6D58D979882601ba8DDa0685B505eA", + "TK_L1BNB": "0x0000000000000000000000000000000000000000", + "TK_L2BNB": "0x4200000000000000000000000000000000000023", + "TK_L1USDC": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + "TK_L2USDC": "0x9F98f9F312D23d078061962837042b8918e6aff2", + "TK_L1BUSD": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", + "TK_L2BUSD": "0x4a2c2838c3907D024916c3f4Fe07832745Ae4bec", + "TK_L1USDT": "0x55d398326f99059fF775485246999027B3197955", + "TK_L2USDT": "0x1E633Dcd0d3D349126983D58988051F7c62c543D", + "TK_L1SUSHI": "0x986cdF0fd180b40c4D6aEAA01Ab740B996D8b782", + "TK_L2SUSHI": "0xa84D7c48602C898EC84C4cCA78651107B3625943", + "L1CrossDomainMessengerFast": "0x0163D3C18781521cf8e72790d15CCF118A540e24", + "Proxy__L1CrossDomainMessengerFast": "0xBe349cABeA97bB933f8C2594634Deb858167f83c", + "L2LiquidityPool": "0xE0DB679377A0F5Ae2BaE485DE475c9e1d8A4607D", + "L1LiquidityPool": "0x43A24672fd6616DA4AA935A17B5aF282375d0F55", + "Proxy__L1LiquidityPool": "0x88b5d70be4fc644c55b164AD09A3DFD44E31eC59", + "Proxy__L2LiquidityPool": "0x5E36d0ADBDEa248c207312d493a08a6d182D0805", + "L2TokenPool": "0xC1778d29c09f220e4fC6d6e8cEDF040e35b09a88", + "L1Message": "0x58EF355c3A6B5036bF6336b5a5afD5B56d48B9e4", + "L2Message": "0xe8D5B98f999e55635f99310E9eBF3Bc0DBb07194", + "AtomicSwap": "0x1148585B2F2a2A3Ce554Dd9a9a25a5D4b5dFB108", + "L2ERC721": "0xA9B4d027CC4985AE76AB09c3de9BCD9Ec529d3cA", + "L2ERC721Reg": "0x05feB25a1aD2bA11949A0788B56c0eD9fFc09944", + "L1NFTBridge": "0xdf10be20f5a457Ad8eAa0c38E3006F275dFC5cE4", + "L2NFTBridge": "0x17bc3bA65463CAf7578df747E2610e90fe9BCe3C", + "Proxy__L1NFTBridge": "0x76bD545C03391d4e6E3d5cC2B5617c94C6038c86", + "Proxy__L2NFTBridge": "0xA774C3f4572C5BA93F75D802ea7Dc6F93228e5cc", + "L1MultiMessageRelayerFast": "0x2dB5717B37Af9A1D9a28829Ea977B4aE4aEE2AED", + "DiscretionaryExitFee": "0xEB6652A4eb6e0d003Fbb3DD76Ae72694175191cd", + "FeedRegistry": "0xC21e15185659D2fB166562bf57f241d50259AB24", + "BOBAUSD_Aggregator": "0x7D5A06bF6b7c793352A380720620d03813680ec1", + "BobaBillingContract": "0x4085c76ca31c8445A57ABc41393d7D57176A505b", + "Proxy__BobaBillingContract": "0xf626b0d7C028E6b89c15ca417f21080E376de65b", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressBobaFuji_0xcE78de95b85212BC348452e91e0e74c17cf37c79.json b/packages/boba/register/addresses/addressBobaFuji_0xcE78de95b85212BC348452e91e0e74c17cf37c79.json new file mode 100644 index 0000000000..a43403c637 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaFuji_0xcE78de95b85212BC348452e91e0e74c17cf37c79.json @@ -0,0 +1,38 @@ +{ + "AddressManager": "0xcE78de95b85212BC348452e91e0e74c17cf37c79", + "Proxy__L1CrossDomainMessenger": "0x68c19B7FbAe4F8034cf6316b2045ba6aB6978F6b", + "Proxy__L1StandardBridge": "0x07B606934b5B5D6A9E1f8b78A0B26215FF58Ad56", + "TK_L1BOBA": "0xEaE78E78cC22690719361F65a50734A15aaE698C", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L1AVAX": "0x0000000000000000000000000000000000000000", + "TK_L2AVAX": "0x4200000000000000000000000000000000000023", + "L1CrossDomainMessengerFast": "0x3C6B8493047b44754EF57129d43d151040871bb7", + "Proxy__L1CrossDomainMessengerFast": "0xBc5249095c890F58C0b75795bd21667eFd123F5F", + "L2LiquidityPool": "0xC5a27088fF840Abc3057C0B5f8B98511033c4867", + "L1LiquidityPool": "0x7BD3DC4aB8087840aB702eb6689d57a60e2143e4", + "Proxy__L1LiquidityPool": "0x30caB2fCA6260FB91B172D4AFB215514069868ea", + "Proxy__L2LiquidityPool": "0x9198b3f5C6acCf05dF8847766A68d992355c18c4", + "L2TokenPool": "0x5edFE3970732EA7878b6e17c1b7Cf27EcF108bC4", + "L1Message": "0x99411339aB22441D6D5f49Ae63deE8c47db85D49", + "L2Message": "0x089489B38e15B21A786791D4409f6E9e2afd7851", + "AtomicSwap": "0x5565f730cab69977E89F21de35f355F2F9fEB1C5", + "L2ERC721": "0xBdBF3b9803DDc910a77bF4852a283Edc055457e5", + "L2ERC721Reg": "0xb1f74c5A3c0cE11d1EB20c03393cc0234254C315", + "L1NFTBridge": "0x8C3E97fdF162615e9e928b4a69b0CB8A738A1910", + "L2NFTBridge": "0xAe34F89F7549903EF99A1cAc77649EA310cC5AAA", + "Proxy__L1NFTBridge": "0xA7A1415eC63Bf410b27AcDAF42fC3c63756E2bFc", + "Proxy__L2NFTBridge": "0x2e59D69cA439b3ab0c1AD8b2762377Afb5C71C7B", + "L1MultiMessageRelayerFast": "0x5e6B412b4fA8373a17aD85B269fA5c354ea57e63", + "DiscretionaryExitFee": "0xED6760E89fB35731ae82d7D149d8c94fdDb376fE", + "FeedRegistry": "0x54CB1E4C1d5F545Ebe9C281927Ee4c0B514b9C33", + "BOBAUSD_Aggregator": "0xF4f9B28F450F3Ecc516D4c91CCFAe52C72c17D33", + "BobaBillingContract": "0xCD50AE5e592ea38bA036aE2a2D6A58f8CAd050BB", + "Proxy__BobaBillingContract": "0xB7E29AB7FB9b6406BAb33Cf6f868fE25B9Ad0160", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "AuthenticatedFaucet": "0x5f6D019832FA4522DB7b94A4fe0DDBb73212FAcE", + "WBOBA9": "0xA7cad1B188Ac7E4d05644D1cf1cBcEB4aD372a9D", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressBobaOpera_0x4e7325bcf09e091Bb8119258B885D4ef687B7386.json b/packages/boba/register/addresses/addressBobaOpera_0x4e7325bcf09e091Bb8119258B885D4ef687B7386.json new file mode 100644 index 0000000000..c560b45fd3 --- /dev/null +++ b/packages/boba/register/addresses/addressBobaOpera_0x4e7325bcf09e091Bb8119258B885D4ef687B7386.json @@ -0,0 +1,49 @@ +{ + "BondManager": "0xCcA5a1CB9fAD5F2A5b88D95440dA7c83EC031Cb1", + "CanonicalTransactionChain": "0x6001C473E020D3562Ea436B61aE4d2e91e7078cE", + "ChainStorageContainer-CTC-batches": "0x282267F1CD5562F91036a1f9FA52961A48385139", + "ChainStorageContainer-CTC-queue": "0x36666Bc3d9FE6fDCfC5Aa1f6e907f36EbF8a8176", + "ChainStorageContainer-SCC-batches": "0x2E3375B06811B3Baed04CC86C691B918155fE176", + "L1MultiMessageRelayer": "0xD8DcA5fC53a83Cf06ec744a7226C23951a353A0f", + "AddressManager": "0x4e7325bcf09e091Bb8119258B885D4ef687B7386", + "OVM_L1CrossDomainMessenger": "0xDEE010E1EedBE26C8AB3AEC8a16Cb974B31068FF", + "Proxy__L1CrossDomainMessenger": "0x64Fca36c52628e40de8684C4C3B5EdB22Fd2eFd9", + "Proxy__L1StandardBridge": "0xb7629EF94B991865940E8A840Aa7d68fa88c3Fe8", + "StateCommitmentChain": "0xF764C4f8D2982432239A110Cf6B08e95631cE564", + "TK_L1BOBA": "0x4389b230D15119c347B9E8BEA6d930A21aaDF6BA", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L2WBOBA": "0x5ad2635e9aBce5F95AdcF164Ac81bcAeBdC8E345", + "TK_L1FTM": "0x0000000000000000000000000000000000000000", + "TK_L2FTM": "0x4200000000000000000000000000000000000023", + "TK_L1USDC": "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75", + "TK_L2USDC": "0xb7629EF94B991865940E8A840Aa7d68fa88c3Fe8", + "TK_L1DAI": "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E", + "TK_L2DAI": "0x31223A147fF76C3fC43d67F8BC36F11E034c484e", + "L1CrossDomainMessengerFast": "0xf74C652a160BA2B2e82D8702A743c8Db83F8DA7d", + "Proxy__L1CrossDomainMessengerFast": "0xC0597ED18446254E4dd0CA5D80eb07D3f2E462cF", + "L2LiquidityPool": "0x4389b230D15119c347B9E8BEA6d930A21aaDF6BA", + "L1LiquidityPool": "0x6eA17632630e43dAF94AA776Eba606Ec5d61Ab6A", + "Proxy__L1LiquidityPool": "0x0bF5402a57970C7BD9883248534B644Ab545e6d4", + "Proxy__L2LiquidityPool": "0xD502Ca71dE5e072918884f638408291c066EF1F6", + "L2TokenPool": "0xEb26f95D155f133Ca3B1fc36C7cFcE7C5239e139", + "L1Message": "0xFa965d70BFF2BCb4B76Ac3A485a28C0D5a06fA9e", + "L2Message": "0xa8082C1D4e8615A962494A7Dd8ffe7be089458eE", + "AtomicSwap": "0xA8b85842b7556F556c0Cf0Af71b9241EA8baDc6F", + "L2ERC721": "0xa2444dC15D92D4cf8B51DAB300C1b8534602Db29", + "L2ERC721Reg": "0x18028b28EE7A8000dCB9e55c6bfaEBC5837AdB79", + "L1NFTBridge": "0x9BE15EC6BF78536a970F444A41361367B5de1098", + "L2NFTBridge": "0x282267F1CD5562F91036a1f9FA52961A48385139", + "Proxy__L1NFTBridge": "0x58bfe4D8108f0657585c9e4C106B3FB8b469eeB9", + "Proxy__L2NFTBridge": "0xd0223931513E72C4cbBE97662C07825C7E71DD9C", + "L1MultiMessageRelayerFast": "0xE7beDcedF3E3054aF891DddeF61775A23a16CB90", + "DiscretionaryExitFee": "0xBD4e12b0634b154932D75503E2Ff404953CbD1Bf", + "FeedRegistry": "0x6001C473E020D3562Ea436B61aE4d2e91e7078cE", + "BOBAUSD_Aggregator": "0x677360aba457B747056f3E00095644D9ADB5753D", + "BobaBillingContract": "0xCcA5a1CB9fAD5F2A5b88D95440dA7c83EC031Cb1", + "Proxy__BobaBillingContract": "0xD5b0E66566FEe76d6c550e7190385703Bcf11354", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressesBobaBase_0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B.json b/packages/boba/register/addresses/addressesBobaBase_0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B.json new file mode 100644 index 0000000000..196d97db68 --- /dev/null +++ b/packages/boba/register/addresses/addressesBobaBase_0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B.json @@ -0,0 +1,40 @@ +{ + "AddressManager": "0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B", + "Proxy__L1StandardBridge": "0xEcca5FEd8154420403549f5d8F123fcE69fae806", + "Proxy__L1CrossDomainMessenger": "0x76DB375075F1d5Dcd1D70Fc07F69a5c7b40ab877", + "TK_L1BOBA": "0x1365fd7BcEE84686DBCA71e1571C0d9ad9E64945", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L1DEV": "0x0000000000000000000000000000000000000000", + "TK_L2DEV": "0x4200000000000000000000000000000000000023", + "TK_L1GLMR": "0x0000000000000000000000000000000000000000", + "TK_L2GLMR": "0x4200000000000000000000000000000000000023", + "L1CrossDomainMessengerFast": "0x7bE12FCB0Fc0979f4DD1A9A1CCec9d0036E634A1", + "Proxy__L1CrossDomainMessengerFast": "0xAE8885D3b7937af9480cd7301925a88Dfb0cE9f6", + "L2LiquidityPool": "0xEb0d3b107528FE17b9F55360D03351fe3D0ACaB2", + "L1LiquidityPool": "0xd779D5e0aDA790f382Cd80d0a90De533b8262b9f", + "Proxy__L1LiquidityPool": "0x569a3e1A4A50D0F53BDF05d50D5FeAB3f716f5A1", + "Proxy__L2LiquidityPool": "0xb227a9FebBa59B8Fe5dF7Ad81afac6E7CdE5a4A5", + "L2TokenPool": "0x152eE45C2eF3E6B303d0603C82b785255D386Fd0", + "L1Message": "0x3C285ACC9CAD39c94CF7E46850bd9098b6f858F5", + "L2Message": "0xECF2d55E35E14eC146f17a17B1D2e082bAA12B40", + "AtomicSwap": "0x2e965d49E69dA6182bdc331b740384CF8745A690", + "L2ERC721": "0x3a93df8eba34AFa4Fb74a09D7cb9BB6E528d2E0C", + "L2ERC721Reg": "0xb73Bc7AbED40236ca53b2225e3FA497c04A0F718", + "L1NFTBridge": "0xf5aCb091936715eCAC49d5759b4801703a175387", + "L2NFTBridge": "0x64371C6b9acFDBC14A98CD794a531Ff737Ef0F98", + "Proxy__L1NFTBridge": "0x1E12Ba552Ac35351563091737910d9E5d1DaD17a", + "Proxy__L2NFTBridge": "0x8E65834B52c3aCc79206a0F09c4b627BC588f09e", + "L1MultiMessageRelayerFast": "0x874a7Ea9722b96924e186f0263866FA90a7C777b", + "DiscretionaryExitFee": "0x01ce26900fC11aBc2AcF53154772bb251c8aA005", + "FeedRegistry": "0x0d2E819A8E0FC9377d3D488A9480D6C00ADE986F", + "BOBAUSD_Aggregator": "0x66335BA50c757a5b1Ee6FB3c3ed703e4a26ea526", + "BobaBillingContract": "0x17CC69Adc242f9C50132503A2e5d5d9cD4889786", + "Proxy__BobaBillingContract": "0x05C9f36D901594D220311B211fA26DbD58B87717", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "AuthenticatedFaucet": "0x8b6A1c0590Ab8A9CED9ADa87Df485eCdd97886E2", + "WBOBA9": "0xc03cc0d0995e7b677348e396F5F1D70Fe8667fCe", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/addressesBobaOperaTestnet_0x12ad9f501149D3FDd703cC10c567F416B7F0af8b.json b/packages/boba/register/addresses/addressesBobaOperaTestnet_0x12ad9f501149D3FDd703cC10c567F416B7F0af8b.json new file mode 100644 index 0000000000..1db2669f4a --- /dev/null +++ b/packages/boba/register/addresses/addressesBobaOperaTestnet_0x12ad9f501149D3FDd703cC10c567F416B7F0af8b.json @@ -0,0 +1,38 @@ +{ + "AddressManager": "0x12ad9f501149D3FDd703cC10c567F416B7F0af8b", + "Proxy__L1CrossDomainMessenger": "0xEecAD665ca933eeA4a9a2db600E538c1391930d1", + "Proxy__L1StandardBridge": "0x86FC7AeFcd69983A8d82eAB1E0EaFD38bB42fd3f", + "TK_L1BOBA": "0x5E747DfA79b8f9e46BE0CC67e378b7600350B2eF", + "TK_L2BOBA": "0x4200000000000000000000000000000000000006", + "TK_L1FTM": "0x0000000000000000000000000000000000000000", + "TK_L2FTM": "0x4200000000000000000000000000000000000023", + "L1CrossDomainMessengerFast": "0x7bE12FCB0Fc0979f4DD1A9A1CCec9d0036E634A1", + "Proxy__L1CrossDomainMessengerFast": "0xE5781E5E9CbC67E91DF93eD01E922De30125e491", + "L2LiquidityPool": "0x00Fda9B3952f80c4238C371064FA6667b6146468", + "L1LiquidityPool": "0x6A27b80a11156A7aA88CF34EC73F130df4f28bED", + "Proxy__L1LiquidityPool": "0x34024168ba3cfa608005b5E9f13389bb2532422A", + "Proxy__L2LiquidityPool": "0xE7Da2a8EBcbBa0Dc6082B8D0faBAcA0176920760", + "L2TokenPool": "0x352d964E9aD016f122dc78Afa5164417907E0FaF", + "L1Message": "0x154128647Ff7fc41DdaD3d09f7c83340140539C5", + "L2Message": "0xa97a909D967B150E27AB58ca6d0cb40B39200Be1", + "AtomicSwap": "0x1bc8Bd8FCAd96ee663b6325F71F818Cce678083D", + "L2ERC721": "0x727207c505c1D95Ef7Ed93f74443D72C155064E7", + "L2ERC721Reg": "0xb5F92c9d10539137C9602A626d7F98823e58f3aA", + "L1NFTBridge": "0xA3f17f06F7F02156692D795a1782105dA530631c", + "L2NFTBridge": "0xEecAD665ca933eeA4a9a2db600E538c1391930d1", + "Proxy__L1NFTBridge": "0x5E52f340D43Ee819dd8a38D55Cc27293603Ac5fb", + "Proxy__L2NFTBridge": "0x310FA48450dF21fBC99b937a7AafBc3B7Af6f6D1", + "L1MultiMessageRelayerFast": "0x9Af237336C29dCbA346764af8e8E1F0ba83D1eE5", + "DiscretionaryExitFee": "0x6E7033f647f932D23de37BD3b25b8F56DeAD4034", + "FeedRegistry": "0x48dfB307f6fFbDB9229E63beA2C127e7500DC5Ae", + "BOBAUSD_Aggregator": "0xA145e444abAd1Cb233A37cED870c59FD97e774bf", + "BobaBillingContract": "0x5E747DfA79b8f9e46BE0CC67e378b7600350B2eF", + "Proxy__BobaBillingContract": "0x675Ea342D2a85D7db0Cc79AE64196ad628Ce8187", + "Boba_GasPriceOracle":"0x4200000000000000000000000000000000000025", + "Proxy__Boba_GasPriceOracle":"0x4200000000000000000000000000000000000024", + "BobaTuringCredit": "0x4200000000000000000000000000000000000021", + "Proxy__BobaTuringCredit": "0x4200000000000000000000000000000000000020", + "AuthenticatedFaucet": "0xCED1459C6B56a85363426a502a24De99fBbF5a83", + "WBOBA9": "0xfd7f8a9F2D11B30a3571395Be9601720B6a32995", + "L2StandardTokenFactory": "0xD2ae16D8c66ac7bc1Cf3c9e5d6bfE5f76BeDb826" +} diff --git a/packages/boba/register/addresses/tokenInfo.json b/packages/boba/register/addresses/tokenInfo.json index 5689658e0f..051dde39e0 100644 --- a/packages/boba/register/addresses/tokenInfo.json +++ b/packages/boba/register/addresses/tokenInfo.json @@ -526,5 +526,323 @@ "decimals": 18 } } + }, + "43114": { + "L1": { + "0x3cD790449CF7D187a143d4Bd7F4654d4f2403e02": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x42006Ab57701251B580bDFc24778C43c9ff589A1": { + "name": "EVO", + "symbol": "EVO", + "decimals": 18 + }, + "0xc7198437980c041c805A1EDcbA50c1Ce5db95118": { + "name": "Tether USD", + "symbol": "USDT.e", + "decimals": 6 + }, + "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7": { + "name": "TetherToken", + "symbol": "USDt", + "decimals": 6 + }, + "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6 + }, + "0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664": { + "name": "USD Coin", + "symbol": "USDC.e", + "decimals": 6 + }, + "0x19860CCB0A68fd4213aB9D8266F7bBf05A8dDe98": { + "name": "Binance USD", + "symbol": "BUSD.e", + "decimals": 18 + }, + "0x9C9e5fD8bbc25984B178FdCE6117Defa39d2db39": { + "name": "BUSD Token", + "symbol": "BUSD", + "decimals": 18 + }, + "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70": { + "name": "Dai Stablecoin", + "symbol": "DAI.e", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0xc8849f32138de93F6097199C5721a9EfD91ceE01": { + "name": "EVO", + "symbol": "EVO", + "decimals": 18 + }, + "0x4ED96c1dc969d7E2310D9582A68c39556C005912": { + "name": "Tether USD", + "symbol": "USDT.e", + "decimals": 6 + }, + "0xfaA13D82756f1e0e4dec9416b83121db3Fc35199": { + "name": "TetherToken", + "symbol": "USDt", + "decimals": 6 + }, + "0x12bb1A120dcF8Cb7152eDAC9f04d176DD7f41F7e": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6 + }, + "0x126969743a6d300bab08F303f104f0f7DBAfbe20": { + "name": "USD Coin", + "symbol": "USDC.e", + "decimals": 6 + }, + "0xb8B0034CFD89925944C07Ac6CcB2834d1774cfb6": { + "name": "Binance USD", + "symbol": "BUSD.e", + "decimals": 18 + }, + "0x87e062dE99Ed71aF9b22dDA63e1b6D43333798f8": { + "name": "BUSD Token", + "symbol": "BUSD", + "decimals": 18 + }, + "0x69B7d24f0E03Ff21949081C95dA7288fEa5C844D": { + "name": "Dai Stablecoin", + "symbol": "DAI.e", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "Avalanche", + "symbol": "AVAX", + "decimals": 18 + } + } + }, + "43113": { + "L1": { + "0xEaE78E78cC22690719361F65a50734A15aaE698C": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "Avalanche", + "symbol": "AVAX", + "decimals": 18 + } + } + }, + "56": { + "L1": { + "0xE0DB679377A0F5Ae2BaE485DE475c9e1d8A4607D": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 18 + }, + "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56": { + "name": "BUSD Token", + "symbol": "BUSD", + "decimals": 18 + }, + "0x55d398326f99059fF775485246999027B3197955": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 18 + }, + "0x986cdF0fd180b40c4D6aEAA01Ab740B996D8b782": { + "name": "SushiToken", + "symbol": "SUSHI", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x9F98f9F312D23d078061962837042b8918e6aff2": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 18 + }, + "0x4a2c2838c3907D024916c3f4Fe07832745Ae4bec": { + "name": "BUSD Token", + "symbol": "BUSD", + "decimals": 18 + }, + "0x1E633Dcd0d3D349126983D58988051F7c62c543D": { + "name": "Tether USD", + "symbol": "USDT", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "BNB", + "symbol": "BNB", + "decimals": 18 + }, + "0xa84D7c48602C898EC84C4cCA78651107B3625943": { + "name": "SushiToken", + "symbol": "SUSHI", + "decimals": 18 + } + } + }, + "97": { + "L1": { + "0x875cD11fDf085e0E11B0EE6b814b6d0b38fA554C": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x02Ed46AA41fcb4a6f06a5F2D43A958F1e8c0A4E6": { + "name": "Meta Token Test", + "symbol": "MTT", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "tBNB", + "symbol": "tBNB", + "decimals": 18 + }, + "0xb3BE5C928E3ec6b11985753f7B3C43A8bB12Bc03": { + "name": "Meta Token Test", + "symbol": "MTT", + "decimals": 18 + } + } + }, + "1284": { + "L1": { + "0x18D17A9fD652D7d6a59903E23792ab97F832Ed6C": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "GLMR", + "symbol": "GLMR", + "decimals": 18 + } + } + }, + "1287": { + "L1": { + "0x1365fd7BcEE84686DBCA71e1571C0d9ad9E64945": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "DEV", + "symbol": "DEV", + "decimals": 18 + } + } + }, + "250": { + "L1": { + "0x4389b230D15119c347B9E8BEA6d930A21aaDF6BA": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6 + }, + "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E": { + "name": "Dai Stablecoin", + "symbol": "DAI", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "FTM", + "symbol": "FTM", + "decimals": 18 + }, + "0xb7629EF94B991865940E8A840Aa7d68fa88c3Fe8": { + "name": "USD Coin", + "symbol": "USDC", + "decimals": 6 + }, + "0x31223A147fF76C3fC43d67F8BC36F11E034c484e": { + "name": "Dai Stablecoin", + "symbol": "DAI", + "decimals": 18 + } + } + }, + "4002": { + "L1": { + "0x5E747DfA79b8f9e46BE0CC67e378b7600350B2eF": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + } + }, + "L2": { + "0x4200000000000000000000000000000000000006": { + "name": "BOBA Token", + "symbol": "BOBA", + "decimals": 18 + }, + "0x4200000000000000000000000000000000000023": { + "name": "FTM", + "symbol": "FTM", + "decimals": 18 + } + } } } diff --git a/packages/sdk/src/utils/contracts.ts b/packages/sdk/src/utils/contracts.ts index b38387ecf2..6e047ad929 100644 --- a/packages/sdk/src/utils/contracts.ts +++ b/packages/sdk/src/utils/contracts.ts @@ -128,6 +128,186 @@ export const CONTRACT_ADDRESSES: { }, l2: DEFAULT_L2_CONTRACT_ADDRESSES, }, + // Moonbeam local + 1281: { + l1: { + AddressManager: '0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3', + L1CrossDomainMessenger: '0xab7785d56697E65c2683c8121Aac93D3A028Ba95', + L1CrossDomainMessengerFast: '0xB942FA2273C7Bce69833e891BDdFd7212d2dA415', + L1StandardBridge: '0x78D714e1b47Bb86FE15788B917C9CC7B77975529', + StateCommitmentChain: '0x294c664f6D63bd1521231a2EeFC26d805ce00a08', + CanonicalTransactionChain: '0x598efcBD0B5b4Fd0142bEAae1a38f6Bd4d8a218d', + BondManager: '0xEC69d4f48f4f1740976968FAb9828d645Ad1d77f', + L1MultiMessageRelayer: '0xad856F238CBeafd064b80D12EadAea3981fB21B5', + L1MultiMessageRelayerFast: '0xAdD0E4aD78B01048027154c7a432a1cB6711178f', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // MoonBase + 1287: { + l1: { + AddressManager: '0xF8d0bF3a1411AC973A606f90B2d1ee0840e5979B', + L1CrossDomainMessenger: '0x76DB375075F1d5Dcd1D70Fc07F69a5c7b40ab877', + L1CrossDomainMessengerFast: '0xAE8885D3b7937af9480cd7301925a88Dfb0cE9f6', + L1StandardBridge: '0xEcca5FEd8154420403549f5d8F123fcE69fae806', + StateCommitmentChain: '0x5E41Eaac5319CDf336c51969E2F164A686138B28', + CanonicalTransactionChain: '0xa8bD51a7F46321587921A33fa3c752b426c74754', + BondManager: '0x6c55306656E8b74F93653A753DE539c2F6ca18Db', + L1MultiMessageRelayer: '0x4c1bcfe4F0b1a57d3c578a8ED3dBEBCa29339c85', + L1MultiMessageRelayerFast: '0x874a7Ea9722b96924e186f0263866FA90a7C777b', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Moonbeam + 1284: { + l1: { + AddressManager: '0x564c10A60af35a07f0EA8Be3106a4D81014b21a0', + L1CrossDomainMessenger: '0x4765f8b50Bbe049045bBA1270dc7A8CDF17165cF', + L1CrossDomainMessengerFast: '0x17d02C3e6cB69225d83d0bADEb0fC09aE735CA3b', + L1StandardBridge: '0xAf5297f68D48cd2DE37Ee5cbaC0647fbA4132985', + StateCommitmentChain: '0xAD379B1518f50Fc737536D2Ec2c13E4640e228A8', + CanonicalTransactionChain: '0x99C970105cf6EE2e22b563CB86bCA42D05ac7A95', + BondManager: '0xcfe333e0e48EC71f1399a76001cf39E0c6A51dA5', + L1MultiMessageRelayer: '0x3664bC9BA25D0d3911c39d8ae1734b0B5A3495C1', + L1MultiMessageRelayerFast: '0xE2EE964E39720f78Cd75BC146Ed078D301981759', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Fantom local + 4003: { + l1: { + AddressManager: '0xf536cAF1a894E09945E649FCE3032E8E03ECb9A0', + L1CrossDomainMessenger: '0x03466593AE8Bc085F384bC4EB91d5035F5a7936C', + L1CrossDomainMessengerFast: '0xC93DD6833E6A29004FcC84C757cCf0d5551aBFe1', + L1StandardBridge: '0xAEa06C2B29edfac53a0538A9843D018348845Ebf', + StateCommitmentChain: '0xC98Dd1b152d9e4cf2A6384a78d4FFE8D50E86C6c', + CanonicalTransactionChain: '0xFfB9dF984DC95ab53c561d818b708135612b087f', + BondManager: '0xE9BC1f638d05edF64Bf3e23A08ff3e2B0fb8b7F7', + L1MultiMessageRelayer: '0x9257aE2144eF338Da70D6884c98BD8CB90Da639E', + L1MultiMessageRelayerFast: '0xB6D431Bb85298030eA27a0E3769bEa5ed1F9fF53', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Fantom testnet + 4002: { + l1: { + AddressManager: '0x12ad9f501149D3FDd703cC10c567F416B7F0af8b', + L1CrossDomainMessenger: '0xEecAD665ca933eeA4a9a2db600E538c1391930d1', + L1CrossDomainMessengerFast: '0xE5781E5E9CbC67E91DF93eD01E922De30125e491', + L1StandardBridge: '0x86FC7AeFcd69983A8d82eAB1E0EaFD38bB42fd3f', + StateCommitmentChain: '0x352d964E9aD016f122dc78Afa5164417907E0FaF', + CanonicalTransactionChain: '0xE66Bd40BBeC97397758E22858331752f0ecBE02e', + BondManager: '0xa97a909D967B150E27AB58ca6d0cb40B39200Be1', + L1MultiMessageRelayer: '0xD7Cbc979C909d864c38670AcccD57209F7B556e3', + L1MultiMessageRelayerFast: '0x9Af237336C29dCbA346764af8e8E1F0ba83D1eE5', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Fantom mainnet + 250: { + l1: { + AddressManager: '0x4e7325bcf09e091Bb8119258B885D4ef687B7386', + L1CrossDomainMessenger: '0x64Fca36c52628e40de8684C4C3B5EdB22Fd2eFd9', + L1CrossDomainMessengerFast: '0xC0597ED18446254E4dd0CA5D80eb07D3f2E462cF', + L1StandardBridge: '0xb7629EF94B991865940E8A840Aa7d68fa88c3Fe8', + StateCommitmentChain: '0xF764C4f8D2982432239A110Cf6B08e95631cE564', + CanonicalTransactionChain: '0x6001C473E020D3562Ea436B61aE4d2e91e7078cE', + BondManager: '0xCcA5a1CB9fAD5F2A5b88D95440dA7c83EC031Cb1', + L1MultiMessageRelayer: '0xD8DcA5fC53a83Cf06ec744a7226C23951a353A0f', + L1MultiMessageRelayerFast: '0xE7beDcedF3E3054aF891DddeF61775A23a16CB90', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Avalanche local + 43112: { + l1: { + AddressManager: '0x52C84043CD9c865236f11d9Fc9F56aa003c1f922', + L1CrossDomainMessenger: '0xDFBb4b49DfAe39720f68f8297ADb2368FeffaDdb', + L1CrossDomainMessengerFast: '0xD054149e4345Cc00cc2f2465C02a864f60d6bd46', + L1StandardBridge: '0x4475A8FBeF5Cf4a92a484B6f5602A91F3abC72D8', + StateCommitmentChain: '0xF5f1f185cF359dC48469e410Aeb6983cD4DC5812', + CanonicalTransactionChain: '0xa1E47689f396fED7d18D797d9D31D727d2c0d483', + BondManager: '0x97C0FE6aB595cbFD50ad3860DA5B2017d8B35c2E', + L1MultiMessageRelayer: '0xEC1bf080BDFBbBa102603Cc1C55aFd215C694a2b', + L1MultiMessageRelayerFast: '0x1AA001Cd20F35F3F4EF1A945053CeE4Acc24aDb4', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Avalanche testnet + 43113: { + l1: { + AddressManager: '0xcE78de95b85212BC348452e91e0e74c17cf37c79', + L1CrossDomainMessenger: '0x68c19B7FbAe4F8034cf6316b2045ba6aB6978F6b', + L1CrossDomainMessengerFast: '0xBc5249095c890F58C0b75795bd21667eFd123F5F', + L1StandardBridge: '0x07B606934b5B5D6A9E1f8b78A0B26215FF58Ad56', + StateCommitmentChain: '0x57B9C47F2Ae857005238096486C5B107447dE221', + CanonicalTransactionChain: '0xA36D21C0125b5Dc52d95ED8FF1eF7188d4666EAE', + BondManager: '0x067cD503bd734a779830dafF0Db582B6a347c3df', + L1MultiMessageRelayer: '0x74546A4c6D5543Be7e8447159c47BAe7f5431C49', + L1MultiMessageRelayerFast: '0x5e6B412b4fA8373a17aD85B269fA5c354ea57e63', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // Avalanche Mainnet + 43114: { + l1: { + AddressManager: '0x00220f8ce1c4be8436574e575fE38558d85e2E6b', + L1CrossDomainMessenger: '0x0fc742332ae6D447d6619D93985Aa288B81CBb0C', + L1CrossDomainMessengerFast: '0x5b6714b7926e6D7e34154C9AC945B489978fA7E7', + L1StandardBridge: '0xf188F1e92B2c78956D2859b84684BFD17103e22c', + StateCommitmentChain: '0x1ef85D873Cf451C8B9a45DbE40b478E991F51210', + CanonicalTransactionChain: '0x1A19A4ce2b3B0A974Df717b6F88c881a69F315e3', + BondManager: '0x26c319B7B2cF823365414d082698C8ac90cbBA63', + L1MultiMessageRelayer: '0x87e062dE99Ed71aF9b22dDA63e1b6D43333798f8', + L1MultiMessageRelayerFast: '0xf9821061774b9693359F582b007A5F1C39d75Ae3', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // BNB local + 99: { + l1: { + AddressManager: '0xC194E4CFa59D2DfC520217dA22E23DF8D4658a37', + L1CrossDomainMessenger: '0x8b8656D5d37C3DC620B80817972E0d9a5267761b', + L1CrossDomainMessengerFast: '0x07B43F437c3A13eeb17EF2beBea046e61502151f', + L1StandardBridge: '0x285766B642eAA86b8052817c827E4472cDb3dd18', + StateCommitmentChain: '0x57a243B34F9232515Fa9FD8D4c2daFd611cF1BCA', + CanonicalTransactionChain: '0x3717E342Bc746c01244fb40e47521945091238ce', + BondManager: '0xcF8dDe2accE564024B4b92ef7db81B0e6698F07f', + L1MultiMessageRelayer: '0x90f502229E1fAa70cCf900B2D14595a5C55B3bE8', + L1MultiMessageRelayerFast: '0x64160054BdD6e53915C221cBBfAAbaf1f80c7f20', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // BNB testnet + 97: { + l1: { + AddressManager: '0xAee1fb3f4353a9060aEC3943fE932b6Efe35CdAa', + L1CrossDomainMessenger: '0x53aD38aE4a63Fe33a86E011F7AF4d3fDe3daD145', + L1CrossDomainMessengerFast: '0xbbD6a271abcC44f6dE284E6051Da76b4fB57458C', + L1StandardBridge: '0xBf0939120b4F5E3196b9E12cAC291e03dD058e9a', + StateCommitmentChain: '0x37FB8bB9EA100CA9a0DE822c9923643ef48Cb8EE', + CanonicalTransactionChain: '0x65f291CDfB05bd1D639DF6268F98594fdacDeCa6', + BondManager: '0x6737867ddd04272a79E7207a008f213e336b00e1', + L1MultiMessageRelayer: '0x5e593AeB2Dbd855D79167831f091B4d959FbB2D1', + L1MultiMessageRelayerFast: '0x0F01394F5fc19bA1B9F669bA79b76c9EaAe37987', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, + // BNB mainnet + 56: { + l1: { + AddressManager: '0xeb989B25597259cfa51Bd396cE1d4B085EC4c753', + L1CrossDomainMessenger: '0x31338a7D5d123E18a9a71447136B54B6D28241ae', + L1CrossDomainMessengerFast: '0xBe349cABeA97bB933f8C2594634Deb858167f83c', + L1StandardBridge: '0x1E0f7f4b2656b14C161f1caDF3076C02908F9ACC', + StateCommitmentChain: '0xeF85fA550e6EC5486121313C895EDe1005e2397f', + CanonicalTransactionChain: '0xA0E38a8FE293E9e95c6A4a882F396F1c80e9e2e4', + BondManager: '0xEB6652A4eb6e0d003Fbb3DD76Ae72694175191cd', + L1MultiMessageRelayer: '0x1E633Dcd0d3D349126983D58988051F7c62c543D', + L1MultiMessageRelayerFast: '0x2dB5717B37Af9A1D9a28829Ea977B4aE4aEE2AED', + }, + l2: DEFAULT_L2_CONTRACT_ADDRESSES, + }, } /** diff --git a/yarn.lock b/yarn.lock index 705a93066b..f072d76571 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23290,6 +23290,11 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== +redux-persist@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" + integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== + redux-thunk@^2.3.0: version "2.4.2" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"