From 30f8e0fdd372d3b3cf74e342cc78d869d3e5a169 Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Thu, 30 Jul 2020 23:18:23 +0200 Subject: [PATCH] refactor web3 connection --- src/providers/OceanProvider/OceanProvider.tsx | 52 ++++++++----------- src/providers/OceanProvider/README.md | 40 ++------------ src/utils/index.ts | 16 ++++++ 3 files changed, 42 insertions(+), 66 deletions(-) diff --git a/src/providers/OceanProvider/OceanProvider.tsx b/src/providers/OceanProvider/OceanProvider.tsx index c70885c..c33a90a 100644 --- a/src/providers/OceanProvider/OceanProvider.tsx +++ b/src/providers/OceanProvider/OceanProvider.tsx @@ -10,6 +10,7 @@ import ProviderStatus from './ProviderStatus' import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib' import Web3Modal, { ICoreOptions } from 'web3modal' import { getDefaultProviders } from './getDefaultProviders' +import { getAccountId, getBalance } from '../..' interface Balance { eth: string | undefined @@ -35,9 +36,11 @@ const OceanContext = createContext(null) function OceanProvider({ config, + web3ModalOpts, children }: { config: Config + web3ModalOpts?: Partial children: any }): ReactElement { const [web3, setWeb3] = useState() @@ -54,13 +57,20 @@ function OceanProvider({ const [status, setStatus] = useState( ProviderStatus.NOT_AVAILABLE ) - const [web3ModalOpts, setWeb3ModalOpts] = useState>() - function init() { + async function init() { Logger.log('Ocean Provider init') window && window.ethereum && (window.ethereum.autoRefreshOnNetworkChange = false) + + Logger.log('Web3Modal init.') + if (web3ModalOpts === undefined) { + web3ModalOpts = await getDefaultProviders() + } + const web3ModalInstance = new Web3Modal(web3ModalOpts) + setWeb3Modal(web3ModalInstance) + Logger.log('Web3Modal instance created.', web3ModalInstance) } // On mount setup Web3Modal instance @@ -68,18 +78,16 @@ function OceanProvider({ init() }, []) - async function connect(opts?: Partial) { - Logger.log('Connecting ....') + // Connect automatically to cached provider if present + useEffect(() => { + if (!web3Modal) return + web3Modal.cachedProvider && connect() + }, [web3Modal]) - if (opts === undefined) { - opts = await getDefaultProviders() - } + async function connect() { + Logger.log('Connecting ...') - const instance = web3Modal || new Web3Modal(opts) - setWeb3Modal(instance) - Logger.log('Web3Modal instance created.', instance) - - const provider = web3Provider || (await instance.connect()) + const provider = await web3Modal.connect() setWeb3Provider(provider) const web3 = new Web3(provider) @@ -115,18 +123,6 @@ function OceanProvider({ web3Modal.clearCachedProvider() } - async function getAccountId(web3: Web3) { - const accounts = await web3.eth.getAccounts() - return accounts[0] - } - - async function getBalance(account: Account) { - const eth = await account.getEtherBalance() - const ocean = await account.getOceanBalance() - - return { eth, ocean } - } - // // Listen for provider, account & network changes // and react to it @@ -137,9 +133,7 @@ function OceanProvider({ const handleAccountsChanged = async (accounts: string[]) => { console.debug("Handling 'accountsChanged' event with payload", accounts) - // if (status === ProviderStatus.CONNECTED) { - connect(web3ModalOpts) - // } + connect() } // ToDo need to handle this, it's not implemented, need to update chainId and reinitialize ocean lib @@ -149,9 +143,7 @@ function OceanProvider({ networkId, status ) - // if (status === ProviderStatus.CONNECTED) { - connect(web3ModalOpts) - // } + connect() } useEffect(() => { diff --git a/src/providers/OceanProvider/README.md b/src/providers/OceanProvider/README.md index 788df92..a268ae5 100644 --- a/src/providers/OceanProvider/README.md +++ b/src/providers/OceanProvider/README.md @@ -18,7 +18,7 @@ import { OceanProvider, Config } from '@oceanprotocol/react' const config: Config = { nodeUri: '', - aquariusUri: '', + metadataStoreUri: '', ... } @@ -27,10 +27,8 @@ export default function MyApp({ }: { children: ReactNode }): ReactNode { - const web3 = await getWeb3() - return ( - +

My App

{children}
@@ -38,48 +36,18 @@ export default function MyApp({ } ``` -The `OceanProvider` requires a Web3 instance to be passed as prop so you can either handle this with your own `getWeb3()`, or use the basic [`Web3Provider`](../Web3Provider): - -```tsx -import React, { ReactNode } from 'react' -import { Web3Provider, OceanProvider, Config } from '@oceanprotocol/react' - -const config: Config = { - nodeUri: '', - aquariusUri: '', - ... -} - -export default function MyApp({ - children -}: { - children: ReactNode -}): ReactNode { - return ( - - {({ web3 }) => ( - -

My App

- {children} -
- )} -
- ) -} -``` - You can then access the provider context values with the `useOcean` hook: ```tsx import { useOcean } from '@oceanprotocol/react' function MyComponent() { - const { ocean, account } = useOcean() + const { ocean, accountId } = useOcean() return (
  • Ocean available: {`${Boolean(ocean)}`}
  • -
  • Account: {account}
  • +
  • Account: {accountId}
) } diff --git a/src/utils/index.ts b/src/utils/index.ts index 358f3f5..1b450b2 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,3 +1,7 @@ +import Web3 from 'web3' +import { Account } from '@oceanprotocol/lib' +import { Balance } from '../providers' + export function readFileContent(file: File): Promise { return new Promise((resolve, reject) => { const reader = new FileReader() @@ -25,3 +29,15 @@ export const publishFeedback: { [key in number]: string } = { 3: '3/4 Publishing asset ...', 4: '4/4 Asset published succesfully' } + +export async function getAccountId(web3: Web3): Promise { + const accounts = await web3.eth.getAccounts() + return accounts[0] +} + +export async function getBalance(account: Account): Promise { + const eth = await account.getEtherBalance() + const ocean = await account.getOceanBalance() + + return { eth, ocean } +}