diff --git a/packages/react-app/src/App.tsx b/packages/react-app/src/App.tsx index 4f8a551..5e8e4c0 100644 --- a/packages/react-app/src/App.tsx +++ b/packages/react-app/src/App.tsx @@ -13,7 +13,6 @@ import { abis, } from '@notestream/contract-artifacts'; import { Contract } from '@ethersproject/contracts'; -import { Web3Provider } from '@ethersproject/providers'; import { useWalletProvider, useNetwork } from './contexts/OnboardContext'; @@ -74,11 +73,10 @@ const App = (): ReactElement => { useEffect(() => { if (appNetworkId && provider) { const { NoteStream } = getContractAddressesForNetwork(appNetworkId); - const signer = new Web3Provider(provider).getSigner(); const noteStreamContract = new Contract( NoteStream, abis.NoteStream, - signer, + provider.getSigner(), ); setStreamContract(noteStreamContract); } diff --git a/packages/react-app/src/components/modals/CreateStreamModal.tsx b/packages/react-app/src/components/modals/CreateStreamModal.tsx index f8efb5a..704b0c2 100644 --- a/packages/react-app/src/components/modals/CreateStreamModal.tsx +++ b/packages/react-app/src/components/modals/CreateStreamModal.tsx @@ -12,7 +12,6 @@ import Grid from '@material-ui/core/Grid'; import moment from 'moment'; import { Contract } from '@ethersproject/contracts'; -import { Web3Provider } from '@ethersproject/providers'; import { createStream } from '../../utils/stream'; import AddressInput from '../form/AddressInput'; @@ -85,7 +84,7 @@ export default function CreateStreamDialog({ const linkedToken = new Contract( zkAsset.linkedTokenAddress, ERC20.abi, - new Web3Provider(provider), + provider, ); const tokenSymbol = linkedToken.symbol(); const tokenDecimals = linkedToken.decimals(); diff --git a/packages/react-app/src/contexts/OnboardContext.tsx b/packages/react-app/src/contexts/OnboardContext.tsx index a2a3295..cd1c637 100644 --- a/packages/react-app/src/contexts/OnboardContext.tsx +++ b/packages/react-app/src/contexts/OnboardContext.tsx @@ -3,6 +3,8 @@ import React, { createContext, ReactElement, useContext, + useState, + useEffect, } from 'react'; import PropTypes from 'prop-types'; @@ -17,6 +19,7 @@ import { WalletInitOptions, // eslint-disable-next-line import/no-unresolved } from 'bnc-onboard/dist/src/interfaces'; +import { Web3Provider } from '@ethersproject/providers'; import { Address } from '../types/types'; interface Props { @@ -112,7 +115,6 @@ class OnboardProvider extends Component { if (ready) { const walletState = onboard.getState(); this.setState({ ...walletState }); - console.log(walletState); } else { // Connection to wallet failed } @@ -166,10 +168,14 @@ export const useSetup = (): Function => { return setup; }; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const useWalletProvider = (): any | null => { +export const useWalletProvider = (): Web3Provider | undefined => { const { provider } = useWallet() || {}; - return provider; + const [web3Provider, setWeb3Provider] = useState(); + + useEffect(() => { + if (provider) setWeb3Provider(new Web3Provider(provider)); + }, [provider]); + return web3Provider; }; export default OnboardProvider; diff --git a/packages/react-app/src/hooks/useENSName.ts b/packages/react-app/src/hooks/useENSName.ts index 5bf8e04..edc013e 100644 --- a/packages/react-app/src/hooks/useENSName.ts +++ b/packages/react-app/src/hooks/useENSName.ts @@ -1,5 +1,4 @@ import { useState, useEffect } from 'react'; -import { Web3Provider } from '@ethersproject/providers'; import { Address } from '../types/types'; import { useWalletProvider } from '../contexts/OnboardContext'; import lookupAddress from '../utils/ens/lookupAddress'; @@ -10,9 +9,7 @@ const useENSName = (address: Address): string => { useEffect(() => { if (provider) { - lookupAddress(new Web3Provider(provider), address).then((name: string) => - setEnsName(name), - ); + lookupAddress(provider, address).then((name: string) => setEnsName(name)); } }, [provider, address]); diff --git a/packages/react-app/src/hooks/useTokenDetails.ts b/packages/react-app/src/hooks/useTokenDetails.ts new file mode 100644 index 0000000..507e083 --- /dev/null +++ b/packages/react-app/src/hooks/useTokenDetails.ts @@ -0,0 +1,40 @@ +import { useEffect, useState } from 'react'; +import { Provider } from '@ethersproject/providers'; +import { Contract } from '@ethersproject/contracts'; + +import { Token, Address } from '../types/types'; +import ERC20 from '../abis/ERC20Detailed'; + +const useTokenDetails = ( + provider?: Provider, + tokenAddress?: Address, +): Token => { + const [tokenDetails, setTokenDetails] = useState({ + name: '', + symbol: '', + decimals: 18, + }); + + useEffect(() => { + if (!provider || !tokenAddress) return; + + const tokenContract = new Contract(tokenAddress, ERC20.abi, provider); + + const updateToken = async (): Promise => { + const tokenName = tokenContract.name(); + const tokenSymbol = tokenContract.symbol(); + const tokenDecimals = tokenContract.decimals(); + setTokenDetails({ + name: await tokenName, + symbol: await tokenSymbol, + decimals: await tokenDecimals, + }); + }; + + updateToken(); + }, [provider, tokenAddress]); + + return tokenDetails; +}; + +export default useTokenDetails; diff --git a/packages/react-app/src/pages/ExchangePage.tsx b/packages/react-app/src/pages/ExchangePage.tsx index 6ebda1b..401f5e2 100644 --- a/packages/react-app/src/pages/ExchangePage.tsx +++ b/packages/react-app/src/pages/ExchangePage.tsx @@ -1,7 +1,5 @@ import React, { ReactElement, useCallback, useEffect, useState } from 'react'; -import { Contract } from '@ethersproject/contracts'; -import { Web3Provider } from '@ethersproject/providers'; import { BigNumber } from '@ethersproject/bignumber'; import { formatUnits, parseUnits } from '@ethersproject/units'; @@ -17,8 +15,7 @@ import { useAztec, useZkAssets } from '../contexts/AztecContext'; import { useAddress, useWalletProvider } from '../contexts/OnboardContext'; import { Address, ZkAsset } from '../types/types'; - -import ERC20 from '../abis/ERC20Detailed'; +import useTokenDetails from '../hooks/useTokenDetails'; const useStyles = makeStyles((theme) => ({ paper: { @@ -40,6 +37,15 @@ const useStyles = makeStyles((theme) => ({ }, })); +const depositZkToken = ( + zkAsset: ZkAsset, + address: Address, + depositAmount: BigNumber, +): void => zkAsset.deposit([{ to: address, amount: depositAmount.toString() }]); + +const withdrawZkToken = (zkAsset: ZkAsset, withdrawAmount: string): void => + zkAsset.withdraw(parseInt(withdrawAmount, 10)); + const ExchangePage = (): ReactElement => { const classes = useStyles(); const userAddress = useAddress(); @@ -53,6 +59,8 @@ const ExchangePage = (): ReactElement => { const [deposit, setDeposit] = useState(true); const [amount, setAmount] = useState(''); + const tokenDetails = useTokenDetails(provider, zkAsset?.linkedTokenAddress); + const updateZkAsset = useCallback( async (address: Address): Promise => { const newZkAsset: ZkAsset = await aztec.zkAsset(address); @@ -74,33 +82,6 @@ const ExchangePage = (): ReactElement => { } }, [aztec.zkAsset, zkAssets, updateZkAsset]); - useEffect(() => { - const updateToken = async (): Promise => { - if (provider && zkAsset?.linkedTokenAddress) { - const linkedToken = new Contract( - zkAsset.linkedTokenAddress, - ERC20.abi, - new Web3Provider(provider), - ); - const tokenSymbol = linkedToken.symbol(); - const tokenDecimals = linkedToken.decimals(); - zkAsset.token.symbol = await tokenSymbol; - zkAsset.token.decimals = await tokenDecimals; - } - }; - updateToken(); - }, [provider, zkAsset]); - - function depositZkToken(depositAmount: BigNumber): void { - if (zkAsset) { - zkAsset.deposit([{ to: userAddress, amount: depositAmount.toString() }]); - } - } - - function withdrawZkToken(withdrawAmount: string): void { - if (zkAsset) zkAsset.withdraw(parseInt(withdrawAmount, 10)); - } - return ( <> @@ -188,15 +169,20 @@ const ExchangePage = (): ReactElement => {