From f168f2021316f018d4e3ef946c9444a1132b04ef Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Mon, 27 Apr 2020 16:29:34 +0200 Subject: [PATCH] Web3Provider concept --- README.md | 44 ++++++++++++++----- src/providers/OceanProvider/OceanProvider.tsx | 9 ++-- src/providers/OceanProvider/utils.ts | 6 +-- src/providers/Web3Provider/README.md | 0 src/providers/Web3Provider/Web3Provider.tsx | 24 ++++++++++ src/providers/Web3Provider/index.ts | 1 + 6 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 src/providers/Web3Provider/README.md create mode 100644 src/providers/Web3Provider/Web3Provider.tsx diff --git a/README.md b/README.md index 2bd4c60..e1026b3 100644 --- a/README.md +++ b/README.md @@ -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 ( - -

My App

- {children} -
+ + {(web3: Web3) => ( + +

My App

+ {children} +
+ )} +
) } ``` +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 diff --git a/src/providers/OceanProvider/OceanProvider.tsx b/src/providers/OceanProvider/OceanProvider.tsx index d4b3208..d17d30e 100644 --- a/src/providers/OceanProvider/OceanProvider.tsx +++ b/src/providers/OceanProvider/OceanProvider.tsx @@ -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() const [aquarius, setAquarius] = useState() const [account, setAccount] = useState() @@ -84,10 +85,10 @@ function OceanProvider({ useEffect(() => { async function debug(): Promise { 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]) diff --git a/src/providers/OceanProvider/utils.ts b/src/providers/OceanProvider/utils.ts index 861669c..3d7269d 100644 --- a/src/providers/OceanProvider/utils.ts +++ b/src/providers/OceanProvider/utils.ts @@ -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] diff --git a/src/providers/Web3Provider/README.md b/src/providers/Web3Provider/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/providers/Web3Provider/Web3Provider.tsx b/src/providers/Web3Provider/Web3Provider.tsx new file mode 100644 index 0000000..b86a42b --- /dev/null +++ b/src/providers/Web3Provider/Web3Provider.tsx @@ -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() + + return ( + + {children} + + ) +} + +// Helper hook to access the provider values +const useWeb3 = (): Web3ProviderValue => useContext(Web3Context) + +export { Web3Provider, useWeb3 } +export default Web3Provider diff --git a/src/providers/Web3Provider/index.ts b/src/providers/Web3Provider/index.ts index e69de29..391081f 100644 --- a/src/providers/Web3Provider/index.ts +++ b/src/providers/Web3Provider/index.ts @@ -0,0 +1 @@ +export * from './Web3Provider'