diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index 254847c..43eb296 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -9,7 +9,6 @@ import HomeIcon from 'remixicon-react/Home3LineIcon' import SettingsIcon from 'remixicon-react/Settings2LineIcon' import AccountIcon from 'remixicon-react/Wallet3LineIcon' import { Context as BeeContext } from '../providers/Bee' -import { Context as TopUpContext } from '../providers/TopUp' import DashboardLogo from '../assets/dashboard-logo.svg' import DesktopLogo from '../assets/desktop-logo.svg' import { config } from '../config' @@ -69,7 +68,6 @@ const useStyles = makeStyles((theme: Theme) => export default function SideBar(): ReactElement { const classes = useStyles() const { isBeeDesktop } = useIsBeeDesktop() - const { providerUrl } = useContext(TopUpContext) const { nodeInfo } = useContext(BeeContext) const navBarItems = [ @@ -86,7 +84,7 @@ export default function SideBar(): ReactElement { }, { label: 'Account', - path: providerUrl === null ? ROUTES.WALLET : ROUTES.ACCOUNT_WALLET, + path: ROUTES.ACCOUNT_WALLET, icon: AccountIcon, pathMatcherSubstring: '/account/', }, diff --git a/src/config.ts b/src/config.ts index 7fa1bfd..a9c5601 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,6 +8,7 @@ class Config { public readonly BEE_DESKTOP_URL: string public readonly SENTRY_KEY: string | undefined public readonly SENTRY_ENVIRONMENT: string | undefined + public readonly DEFAULT_RPC_URL: string constructor() { this.BEE_API_HOST = sessionStorage.getItem('api_host') ?? process.env.REACT_APP_BEE_HOST ?? 'http://localhost:1633' @@ -21,6 +22,7 @@ class Config { this.BEE_DISCORD_HOST = process.env.REACT_APP_BEE_DISCORD_HOST ?? 'https://discord.gg/eKr9XPv7' this.GITHUB_REPO_URL = process.env.REACT_APP_BEE_GITHUB_REPO_URL ?? 'https://api.github.com/repos/ethersphere/bee' this.BEE_DESKTOP_URL = process.env.REACT_APP_BEE_DESKTOP_URL ?? window.location.origin + this.DEFAULT_RPC_URL = process.env.REACT_APP_DEFAULT_RPC_URL ?? 'https://xdai.fairdatasociety.org' } } diff --git a/src/pages/account/wallet/AccountWallet.tsx b/src/pages/account/wallet/AccountWallet.tsx index a0c2555..b6ee616 100644 --- a/src/pages/account/wallet/AccountWallet.tsx +++ b/src/pages/account/wallet/AccountWallet.tsx @@ -29,7 +29,7 @@ export function AccountWallet(): ReactElement { } function onDeposit() { - navigate(ROUTES.CONFIRMATION) + navigate(ROUTES.TOP_UP) } return ( diff --git a/src/pages/gift-code/index.tsx b/src/pages/gift-code/index.tsx index 58f1195..9d860a1 100644 --- a/src/pages/gift-code/index.tsx +++ b/src/pages/gift-code/index.tsx @@ -29,7 +29,6 @@ export default function Index(): ReactElement { useEffect(() => { async function mapGiftWallets() { - if (!provider) return const results = [] for (const giftWallet of giftWallets) { results.push(await ResolvedWallet.make(giftWallet, provider)) diff --git a/src/pages/info/index.tsx b/src/pages/info/index.tsx index f755145..37b605b 100644 --- a/src/pages/info/index.tsx +++ b/src/pages/info/index.tsx @@ -51,7 +51,7 @@ export default function Status(): ReactElement { buttonProps={{ iconType: Wallet, children: 'Setup wallet', - onClick: () => navigate(ROUTES.WALLET), + onClick: () => navigate(ROUTES.TOP_UP), }} icon={} title="Your wallet is not setup." diff --git a/src/pages/rpc/Confirmation.tsx b/src/pages/rpc/Confirmation.tsx deleted file mode 100644 index 9cbacee..0000000 --- a/src/pages/rpc/Confirmation.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { Box, createStyles, Grid, makeStyles, Typography } from '@material-ui/core' -import { ReactElement, useContext, useState } from 'react' -import Check from 'remixicon-react/CheckLineIcon' -import BankCard from 'remixicon-react/BankCard2LineIcon' -import MoneyDollarCircle from 'remixicon-react/MoneyDollarCircleLineIcon' -import Gift from 'remixicon-react/GiftLineIcon' -import { useNavigate } from 'react-router' -import ExpandableListItemActions from '../../components/ExpandableListItemActions' -import { HistoryHeader } from '../../components/HistoryHeader' -import { SwarmButton } from '../../components/SwarmButton' -import { ROUTES } from '../../routes' -import { Context as BeeContext } from '../../providers/Bee' -import { Context as TopUpContext } from '../../providers/TopUp' -import { useIsBeeDesktop } from '../../hooks/apiHooks' -import { BeeModes } from '@ethersphere/bee-js' -import { restartBeeNode, upgradeToLightNode } from '../../utils/desktop' -import { Loading } from '../../components/Loading' -import { useSnackbar } from 'notistack' - -const useStyles = makeStyles(() => - createStyles({ - checkWrapper: { - background: 'rgba(0, 230, 118, 0.25)', - borderRadius: 99999, - width: '180px', - height: '180px', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - }, - }), -) - -const MINIMUM_XDAI = '0.05' -const MINIMUM_XBZZ = '0.1' - -export default function Confirmation(): ReactElement { - const navigate = useNavigate() - const styles = useStyles() - const { isBeeDesktop } = useIsBeeDesktop() - const { balance, nodeInfo } = useContext(BeeContext) - const { providerUrl } = useContext(TopUpContext) - const [loading, setLoading] = useState(false) - const { enqueueSnackbar } = useSnackbar() - - const canUpgradeToLightNode = - isBeeDesktop && - nodeInfo?.beeMode === BeeModes.ULTRA_LIGHT && - balance?.dai.toDecimal.gte(MINIMUM_XDAI) && - balance?.bzz.toDecimal.gte(MINIMUM_XBZZ) - - async function restart() { - if (!providerUrl) { - return - } - setLoading(true) - try { - await upgradeToLightNode(providerUrl) - await restartBeeNode() - enqueueSnackbar('Upgraded to light node', { variant: 'success' }) - navigate(ROUTES.RESTART_LIGHT) - } catch (error) { - enqueueSnackbar(`Failed to upgrade: ${error}`, { variant: 'error' }) - } - setLoading(false) - } - - if (!balance) { - return - } - - return ( - <> - Connect to the blockchain - - -
- -
-
- - Your node's RPC endpoint is set up correctly! - - - Lastly, you will need to top-up your node wallet. - - If you're not familiar with cryptocurrencies, you can start with a bank card. - - - - navigate(ROUTES.TOP_UP_GIFT_CODE)}> - Use a gift code - - navigate(ROUTES.TOP_UP_CRYPTO)}> - Use DAI - - navigate(ROUTES.TOP_UP_BANK_CARD)}> - Get started with bank card - - - {canUpgradeToLightNode && ( - <> - - - It seems that you have enough balance to upgrade your bee node to light node. By upgrading you will gain - access to file upload and faster downloads. - - - - - Upgrade now - -
- - - )} - - - ) -} diff --git a/src/pages/rpc/index.tsx b/src/pages/rpc/index.tsx deleted file mode 100644 index 87d51f4..0000000 --- a/src/pages/rpc/index.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { Box, Typography } from '@material-ui/core' -import { useSnackbar } from 'notistack' -import { ReactElement, useContext, useState } from 'react' -import Check from 'remixicon-react/CheckLineIcon' -import { useNavigate } from 'react-router' -import { providers } from 'ethers' -import { HistoryHeader } from '../../components/HistoryHeader' -import { SwarmButton } from '../../components/SwarmButton' -import { SwarmTextInput } from '../../components/SwarmTextInput' -import { Context } from '../../providers/TopUp' -import { ROUTES } from '../../routes' -import { Rpc } from '../../utils/rpc' - -export default function Index(): ReactElement { - const { providerUrl, setProviderUrl } = useContext(Context) - const [localProviderUrl, setLocalProviderUrl] = useState(providerUrl) - - const { enqueueSnackbar } = useSnackbar() - const navigate = useNavigate() - - async function onSubmit() { - if (!localProviderUrl) return - - try { - await Rpc.eth_getBlockByNumber(new providers.JsonRpcProvider(localProviderUrl)) - enqueueSnackbar('Connected to RPC provider successfully.', { variant: 'success' }) - setProviderUrl(localProviderUrl) - navigate(ROUTES.CONFIRMATION) - } catch (error) { - enqueueSnackbar('Could not connect to RPC provider.', { variant: 'error' }) - } - } - - return ( - <> - Connect to the blockchain - - Set up RPC endpoint - - - - To connect to and retrieve data from the blockchain, you'll need to connect to a publicly-provided node - via the node's RPC endpoint. If you're not familiar with this, please read{' '} - - this guide - - . - - - - setLocalProviderUrl(event.target.value)} - defaultValue={providerUrl || ''} - /> - - - Connect - - - ) -} diff --git a/src/pages/top-up/Balance.tsx b/src/pages/top-up/Balance.tsx new file mode 100644 index 0000000..2f3c71f --- /dev/null +++ b/src/pages/top-up/Balance.tsx @@ -0,0 +1,60 @@ +import { Box, Grid, Typography } from '@material-ui/core' +import { ReactElement, useContext } from 'react' +import { useNavigate } from 'react-router' +import Check from 'remixicon-react/CheckLineIcon' +import ExpandableListItem from '../../components/ExpandableListItem' +import ExpandableListItemKey from '../../components/ExpandableListItemKey' +import { HistoryHeader } from '../../components/HistoryHeader' +import { Loading } from '../../components/Loading' +import { SwarmButton } from '../../components/SwarmButton' +import { SwarmDivider } from '../../components/SwarmDivider' +import { Context } from '../../providers/Bee' +import { TopUpProgressIndicator } from './TopUpProgressIndicator' + +const MINIMUM_XDAI = '0.5' + +interface Props { + header: string + title: string + p: ReactElement + next: string +} + +export default function Index({ header, title, p, next }: Props): ReactElement { + const { nodeAddresses, balance } = useContext(Context) + const navigate = useNavigate() + + if (!balance || !nodeAddresses) { + return + } + + const disabled = balance.dai.toDecimal.lt(MINIMUM_XDAI) + + return ( + <> + {header} + + + + + {title} + + {p} + + + + + + + + + navigate(next)} disabled={disabled}> + Proceed + + {disabled ? ( + Please deposit at least {MINIMUM_XDAI} xDAI to the address above in order to proceed. + ) : null} + + + ) +} diff --git a/src/pages/top-up/BankCardTopUpIndex.tsx b/src/pages/top-up/BankCardTopUpIndex.tsx index 76f2585..1488839 100644 --- a/src/pages/top-up/BankCardTopUpIndex.tsx +++ b/src/pages/top-up/BankCardTopUpIndex.tsx @@ -1,11 +1,11 @@ import { Typography } from '@material-ui/core' import { ReactElement } from 'react' -import Index from '.' +import Balance from './Balance' import { ROUTES } from '../../routes' export function BankCardTopUpIndex(): ReactElement { return ( - + createStyles({ + checkWrapper: { + background: 'rgba(0, 230, 118, 0.25)', + borderRadius: 99999, + width: '180px', + height: '180px', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + }, + }), +) -interface Props { - header: string - title: string - p: ReactElement - next: string -} +const MINIMUM_XDAI = '0.05' +const MINIMUM_XBZZ = '0.1' -export default function Index({ header, title, p, next }: Props): ReactElement { - const { nodeAddresses, balance } = useContext(Context) +export default function TopUp(): ReactElement { const navigate = useNavigate() + const styles = useStyles() + const { isBeeDesktop } = useIsBeeDesktop() + const { balance, nodeInfo } = useContext(BeeContext) + const { providerUrl } = useContext(TopUpContext) + const [loading, setLoading] = useState(false) + const { enqueueSnackbar } = useSnackbar() - if (!balance || !nodeAddresses) { + const canUpgradeToLightNode = + isBeeDesktop && + nodeInfo?.beeMode === BeeModes.ULTRA_LIGHT && + balance?.dai.toDecimal.gte(MINIMUM_XDAI) && + balance?.bzz.toDecimal.gte(MINIMUM_XBZZ) + + async function restart() { + setLoading(true) + try { + await upgradeToLightNode(providerUrl) + await restartBeeNode() + enqueueSnackbar('Upgraded to light node', { variant: 'success' }) + navigate(ROUTES.RESTART_LIGHT) + } catch (error) { + enqueueSnackbar(`Failed to upgrade: ${error}`, { variant: 'error' }) + } + setLoading(false) + } + + if (!balance) { return } - const disabled = balance.dai.toDecimal.lt(MINIMUM_XDAI) - return ( <> - {header} - - - - - {title} - - {p} - - - - - - - - - navigate(next)} disabled={disabled}> - Proceed - - {disabled ? ( - Please deposit at least {MINIMUM_XDAI} xDAI to the address above in order to proceed. - ) : null} + Account + + +
+ +
+
+ + Transfer funds to your Swarm account + + + Top up your account with xBZZ and xDAI. + + If you're not familiar with cryptocurrencies, you can start with a bank card. + + + + navigate(ROUTES.TOP_UP_GIFT_CODE)}> + Use a gift code + + navigate(ROUTES.TOP_UP_CRYPTO)}> + Use xDAI + + navigate(ROUTES.TOP_UP_BANK_CARD)}> + Get started with bank card + + + {canUpgradeToLightNode && ( + <> + + + It seems that you have enough balance to upgrade your bee node to light node. By upgrading you will gain + access to file upload and faster downloads. + + + + + Upgrade now + +
+ + + )} ) diff --git a/src/providers/TopUp.tsx b/src/providers/TopUp.tsx index 376b4c2..7f9c40f 100644 --- a/src/providers/TopUp.tsx +++ b/src/providers/TopUp.tsx @@ -1,5 +1,6 @@ import { providers, Wallet } from 'ethers' import { createContext, ReactElement, useEffect, useState } from 'react' +import config from '../config' import { setJsonRpcInDesktop } from '../utils/desktop' const LocalStorageKeys = { @@ -10,18 +11,18 @@ const LocalStorageKeys = { } interface ContextInterface { - providerUrl: string | null - provider: providers.JsonRpcProvider | null + providerUrl: string + provider: providers.JsonRpcProvider giftWallets: Wallet[] setProviderUrl: (providerUrl: string) => void addGiftWallet: (wallet: Wallet) => void } -const providerUrl = localStorage.getItem('json-rpc-provider') || null +const providerUrl = localStorage.getItem('json-rpc-provider') || config.DEFAULT_RPC_URL const initialValues: ContextInterface = { providerUrl, - provider: providerUrl ? new providers.JsonRpcProvider(providerUrl) : null, + provider: new providers.JsonRpcProvider(providerUrl), giftWallets: [], setProviderUrl: () => {}, // eslint-disable-line addGiftWallet: () => {}, // eslint-disable-line diff --git a/src/routes.tsx b/src/routes.tsx index cc2830b..d03e3c1 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -14,8 +14,7 @@ import { UploadLander } from './pages/files/UploadLander' import GiftCards from './pages/gift-code' import Info from './pages/info' import LightModeRestart from './pages/restart/LightModeRestart' -import Wallet from './pages/rpc' -import Confirmation from './pages/rpc/Confirmation' +import TopUp from './pages/top-up' import Settings from './pages/settings' import { CreatePostageStampPage } from './pages/stamps/CreatePostageStampPage' import Status from './pages/status' @@ -34,8 +33,7 @@ export enum ROUTES { HASH = '/files/hash/:hash', SETTINGS = '/settings', STATUS = '/status', - WALLET = '/account/wallet/top-up', - CONFIRMATION = '/account/wallet/top-up/confirmation', + TOP_UP = '/account/wallet/top-up', TOP_UP_CRYPTO = '/account/wallet/top-up/crypto', TOP_UP_CRYPTO_SWAP = '/account/wallet/top-up/crypto/swap', TOP_UP_BANK_CARD = '/account/wallet/top-up/bank-card', @@ -70,8 +68,7 @@ const BaseRouter = (): ReactElement => ( } /> } /> } /> - } /> - } /> + } /> } /> } /> } />