Web3Provider concept

This commit is contained in:
Matthias Kretschmann 2020-04-27 16:29:34 +02:00
parent 44b145a2ba
commit f168f20213
Signed by: m
GPG Key ID: 606EEEF3C479A91F
6 changed files with 67 additions and 17 deletions

View File

@ -20,6 +20,8 @@
- [🏗 Installation](#-installation)
- [🏄 Usage](#-usage)
- [Providers](#providers)
- [Hooks](#hooks)
- [🦑 Development](#-development)
- [✨ Code Style](#-code-style)
- [👩‍🔬 Testing](#-testing)
@ -38,27 +40,49 @@ npm install @oceanprotocol/react
## 🏄 Usage
First, wrap your App with the `OceanProvider` and provide its config object:
First, wrap your App with the `Web3Provider` and the `OceanProvider`.
### Providers
```tsx
import React from 'react'
import { OceanProvider, Config } from '@oceanprotocol/react'
import React, { ReactNode } from 'react'
import Web3 from 'web3'
import { Web3Provider, OceanProvider, Config } from '@oceanprotocol/react'
const config: Config = {
nodeUri: '',
...
nodeUri: '',
aquariusUri: ''
}
export default function MyApp({ children }: { children: React.ReactNode }): React.ReactNode {
export default function MyApp({
children
}: {
children: ReactNode
}): ReactNode {
return (
<OceanProvider config={config}>
<h1>My App</h1>
{children}
</OceanProvider>
<Web3Provider>
{(web3: Web3) => (
<OceanProvider config={config} web3={web3}>
<h1>My App</h1>
{children}
</OceanProvider>
)}
</Web3Provider>
)
}
```
The `OceanProvider` requires a Web3 instance to be passed as prop. To get you started, we added a basic `Web3Provider` which assumes an injected provider (like MetaMask), and will ask for permissions automatically on first mount.
We suggest you replace this provider with a more complete solution, since there are many UX considerations not handled in that basic provider, like activate only on user intent, listen for account & network changes, display connection instructions and errors, etc.
Some great solutions we liked to work with:
- [web3-react](https://github.com/NoahZinsmeister/web3-react)
- [web3modal](https://github.com/web3modal/web3modal)
### Hooks
Then within your component use the provided hooks to interact with Ocean's functionality. Each hook can be used independently:
```tsx

View File

@ -6,6 +6,7 @@ import React, {
createContext
} from 'react'
import { Ocean, Config, Account, Aquarius, Logger } from '@oceanprotocol/squid'
import Web3 from 'web3'
import Balance from '@oceanprotocol/squid/dist/node/models/Balance'
import { connectOcean } from './utils'
@ -29,13 +30,13 @@ const OceanContext = createContext(null)
function OceanProvider({
config,
web3,
children
}: {
config: Config
web3: Web3
children: ReactNode
}): ReactNode {
// TODO: handle web3
const { web3 } = useWeb3()
const [ocean, setOcean] = useState<Ocean | undefined>()
const [aquarius, setAquarius] = useState<Aquarius | undefined>()
const [account, setAccount] = useState<Account | undefined>()
@ -84,10 +85,10 @@ function OceanProvider({
useEffect(() => {
async function debug(): Promise<void> {
if (!ocean) return
console.debug(
Logger.debug(
`Ocean instance initiated with:\n ${JSON.stringify(config, null, 2)}`
)
console.debug(await ocean.versions.get())
Logger.debug(await ocean.versions.get())
}
debug()
}, [ocean])

View File

@ -1,4 +1,4 @@
import { Ocean, Config, Account } from '@oceanprotocol/squid'
import { Ocean, Config, Account, Logger } from '@oceanprotocol/squid'
import Balance from '@oceanprotocol/squid/dist/node/models/Balance'
import Web3 from 'web3'
@ -11,12 +11,12 @@ export async function connectOcean(
accountId: string
balance: Balance
}> {
console.debug('Connecting to Ocean...')
Logger.debug('Connecting to Ocean...')
const ocean = await Ocean.getInstance({
web3Provider: web3.currentProvider,
...config
})
console.debug('Ocean instance ready.')
Logger.debug('Ocean instance ready.')
const oceanAccounts = await ocean.accounts.list()
const account = oceanAccounts[0]

View File

View File

@ -0,0 +1,24 @@
import React, { ReactNode, useContext, useState, createContext } from 'react'
import Web3 from 'web3'
interface Web3ProviderValue {
web3: Web3
}
const Web3Context = createContext(null)
function Web3Provider({ children }: { children: ReactNode }): ReactNode {
const [web3, setWeb3] = useState<Web3 | undefined>()
return (
<Web3Context.Provider value={{ web3 } as Web3ProviderValue}>
{children}
</Web3Context.Provider>
)
}
// Helper hook to access the provider values
const useWeb3 = (): Web3ProviderValue => useContext(Web3Context)
export { Web3Provider, useWeb3 }
export default Web3Provider

View File

@ -0,0 +1 @@
export * from './Web3Provider'