1
0
mirror of https://github.com/oceanprotocol/react.git synced 2024-12-25 02:26:25 +01:00

refactor web3 connection

This commit is contained in:
Matthias Kretschmann 2020-07-30 23:18:23 +02:00
parent be45942132
commit 30f8e0fdd3
Signed by: m
GPG Key ID: 606EEEF3C479A91F
3 changed files with 42 additions and 66 deletions

View File

@ -10,6 +10,7 @@ import ProviderStatus from './ProviderStatus'
import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib' import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib'
import Web3Modal, { ICoreOptions } from 'web3modal' import Web3Modal, { ICoreOptions } from 'web3modal'
import { getDefaultProviders } from './getDefaultProviders' import { getDefaultProviders } from './getDefaultProviders'
import { getAccountId, getBalance } from '../..'
interface Balance { interface Balance {
eth: string | undefined eth: string | undefined
@ -35,9 +36,11 @@ const OceanContext = createContext(null)
function OceanProvider({ function OceanProvider({
config, config,
web3ModalOpts,
children children
}: { }: {
config: Config config: Config
web3ModalOpts?: Partial<ICoreOptions>
children: any children: any
}): ReactElement { }): ReactElement {
const [web3, setWeb3] = useState<Web3 | undefined>() const [web3, setWeb3] = useState<Web3 | undefined>()
@ -54,13 +57,20 @@ function OceanProvider({
const [status, setStatus] = useState<ProviderStatus>( const [status, setStatus] = useState<ProviderStatus>(
ProviderStatus.NOT_AVAILABLE ProviderStatus.NOT_AVAILABLE
) )
const [web3ModalOpts, setWeb3ModalOpts] = useState<Partial<ICoreOptions>>()
function init() { async function init() {
Logger.log('Ocean Provider init') Logger.log('Ocean Provider init')
window && window &&
window.ethereum && window.ethereum &&
(window.ethereum.autoRefreshOnNetworkChange = false) (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 // On mount setup Web3Modal instance
@ -68,18 +78,16 @@ function OceanProvider({
init() init()
}, []) }, [])
async function connect(opts?: Partial<ICoreOptions>) { // Connect automatically to cached provider if present
Logger.log('Connecting ....') useEffect(() => {
if (!web3Modal) return
web3Modal.cachedProvider && connect()
}, [web3Modal])
if (opts === undefined) { async function connect() {
opts = await getDefaultProviders() Logger.log('Connecting ...')
}
const instance = web3Modal || new Web3Modal(opts) const provider = await web3Modal.connect()
setWeb3Modal(instance)
Logger.log('Web3Modal instance created.', instance)
const provider = web3Provider || (await instance.connect())
setWeb3Provider(provider) setWeb3Provider(provider)
const web3 = new Web3(provider) const web3 = new Web3(provider)
@ -115,18 +123,6 @@ function OceanProvider({
web3Modal.clearCachedProvider() 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 // Listen for provider, account & network changes
// and react to it // and react to it
@ -137,9 +133,7 @@ function OceanProvider({
const handleAccountsChanged = async (accounts: string[]) => { const handleAccountsChanged = async (accounts: string[]) => {
console.debug("Handling 'accountsChanged' event with payload", accounts) console.debug("Handling 'accountsChanged' event with payload", accounts)
// if (status === ProviderStatus.CONNECTED) { connect()
connect(web3ModalOpts)
// }
} }
// ToDo need to handle this, it's not implemented, need to update chainId and reinitialize ocean lib // ToDo need to handle this, it's not implemented, need to update chainId and reinitialize ocean lib
@ -149,9 +143,7 @@ function OceanProvider({
networkId, networkId,
status status
) )
// if (status === ProviderStatus.CONNECTED) { connect()
connect(web3ModalOpts)
// }
} }
useEffect(() => { useEffect(() => {

View File

@ -18,35 +18,7 @@ import { OceanProvider, Config } from '@oceanprotocol/react'
const config: Config = { const config: Config = {
nodeUri: '', nodeUri: '',
aquariusUri: '', metadataStoreUri: '',
...
}
export default function MyApp({
children
}: {
children: ReactNode
}): ReactNode {
const web3 = await getWeb3()
return (
<OceanProvider config={config} web3={web3}>
<h1>My App</h1>
{children}
</OceanProvider>
)
}
```
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: '',
... ...
} }
@ -56,14 +28,10 @@ export default function MyApp({
children: ReactNode children: ReactNode
}): ReactNode { }): ReactNode {
return ( return (
<Web3Provider> <OceanProvider config={config} web3ModalOpts={web3ModalOpts}>
{({ web3 }) => (
<OceanProvider config={config} web3={web3}>
<h1>My App</h1> <h1>My App</h1>
{children} {children}
</OceanProvider> </OceanProvider>
)}
</Web3Provider>
) )
} }
``` ```
@ -74,12 +42,12 @@ You can then access the provider context values with the `useOcean` hook:
import { useOcean } from '@oceanprotocol/react' import { useOcean } from '@oceanprotocol/react'
function MyComponent() { function MyComponent() {
const { ocean, account } = useOcean() const { ocean, accountId } = useOcean()
return ( return (
<ul> <ul>
<li>Ocean available: {`${Boolean(ocean)}`}</li> <li>Ocean available: {`${Boolean(ocean)}`}</li>
<li>Account: {account}</li> <li>Account: {accountId}</li>
</ul> </ul>
) )
} }

View File

@ -1,3 +1,7 @@
import Web3 from 'web3'
import { Account } from '@oceanprotocol/lib'
import { Balance } from '../providers'
export function readFileContent(file: File): Promise<string> { export function readFileContent(file: File): Promise<string> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const reader = new FileReader() const reader = new FileReader()
@ -25,3 +29,15 @@ export const publishFeedback: { [key in number]: string } = {
3: '3/4 Publishing asset ...', 3: '3/4 Publishing asset ...',
4: '4/4 Asset published succesfully' 4: '4/4 Asset published succesfully'
} }
export async function getAccountId(web3: Web3): Promise<string> {
const accounts = await web3.eth.getAccounts()
return accounts[0]
}
export async function getBalance(account: Account): Promise<Balance> {
const eth = await account.getEtherBalance()
const ocean = await account.getOceanBalance()
return { eth, ocean }
}