1
0
mirror of https://github.com/oceanprotocol/react.git synced 2025-02-14 21:10:38 +01:00

Merge branch 'master' into feature/consume

This commit is contained in:
mihaisc 2020-08-03 11:41:12 +03:00
commit 7183dd97c6
16 changed files with 3441 additions and 6195 deletions

View File

@ -4,11 +4,32 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [v0.0.30](https://github.com/oceanprotocol/react/compare/v0.0.29...v0.0.30)
> 31 July 2020
- refactor web3 connection [`#66`](https://github.com/oceanprotocol/react/pull/66)
- update example [`fd1e4f0`](https://github.com/oceanprotocol/react/commit/fd1e4f0a5752d61c01435d2745fa78d144fbf8c9)
- update docs [`f2573be`](https://github.com/oceanprotocol/react/commit/f2573bee232c102c73bef0c17b068763e1b6d72d)
- error catching for connect, todo cleanup [`d68ccb9`](https://github.com/oceanprotocol/react/commit/d68ccb9ff946d4f3dc03cb703b38092bc313e963)
#### [v0.0.29](https://github.com/oceanprotocol/react/compare/v0.0.28...v0.0.29)
> 30 July 2020
- Bump @release-it/bumper from 1.4.0 to 1.4.1 [`#64`](https://github.com/oceanprotocol/react/pull/64)
- Bump release-it from 13.6.5 to 13.6.6 [`#63`](https://github.com/oceanprotocol/react/pull/63)
- Bump web3modal from 1.8.0 to 1.9.0 [`#65`](https://github.com/oceanprotocol/react/pull/65)
- package updates [`51336a0`](https://github.com/oceanprotocol/react/commit/51336a005ef1f8a261fdb24b85694db5f19bdcd7)
- publish update [`519a762`](https://github.com/oceanprotocol/react/commit/519a762762082f5b2db88124f7a5f149ebb24710)
- lazy handle account & network change [`942b542`](https://github.com/oceanprotocol/react/commit/942b542e8b4babbd4b29b13dfacb67f2a8ef357d)
#### [v0.0.28](https://github.com/oceanprotocol/react/compare/v0.0.27...v0.0.28) #### [v0.0.28](https://github.com/oceanprotocol/react/compare/v0.0.27...v0.0.28)
> 22 July 2020 > 22 July 2020
- package updates [`1c73302`](https://github.com/oceanprotocol/react/commit/1c7330203f6d5e978eb0d418cb9691b863681cc7) - package updates [`1c73302`](https://github.com/oceanprotocol/react/commit/1c7330203f6d5e978eb0d418cb9691b863681cc7)
- Release 0.0.28 [`e410504`](https://github.com/oceanprotocol/react/commit/e410504c1fca78ac6e90b604969a7b6a2b782188)
- fix useMetadata fallback [`17ed5f1`](https://github.com/oceanprotocol/react/commit/17ed5f1013a08cefaac021b8265064ca13cc1cef) - fix useMetadata fallback [`17ed5f1`](https://github.com/oceanprotocol/react/commit/17ed5f1013a08cefaac021b8265064ca13cc1cef)
#### [v0.0.27](https://github.com/oceanprotocol/react/compare/v0.0.26...v0.0.27) #### [v0.0.27](https://github.com/oceanprotocol/react/compare/v0.0.26...v0.0.27)

View File

@ -15,16 +15,16 @@
![iu](https://user-images.githubusercontent.com/90316/80356686-1650c080-887a-11ea-854e-bdc2bbdb0c20.jpeg) ![iu](https://user-images.githubusercontent.com/90316/80356686-1650c080-887a-11ea-854e-bdc2bbdb0c20.jpeg)
**WE ARE IN HARDWARE MODE. This project is in a conceptual phase and most stuff does not work yet.** **WE ARE IN HARDWARE MODE. This project is in a conceptual phase and most stuff changes weekly. More importantly, it only works against bleeding edge v3 components of Ocean Protocol which are not completely public yet.**
--- ---
**Table of Contents** **Table of Contents**
- [🏗 Installation](#-installation) - [🏗 Installation](#-installation)
- [🏄 Usage](#-usage) - [🏄 Quick Start](#-quick-start)
- [1. Providers](#1-providers) - [1. Add Provider](#1-add-provider)
- [2. Hooks](#2-hooks) - [2. Use Hooks](#2-use-hooks)
- [🦑 Development](#-development) - [🦑 Development](#-development)
- [✨ Code Style](#-code-style) - [✨ Code Style](#-code-style)
- [👩‍🔬 Testing](#-testing) - [👩‍🔬 Testing](#-testing)
@ -43,62 +43,25 @@
npm install @oceanprotocol/react npm install @oceanprotocol/react
``` ```
## 🏄 Usage ## 🏄 Quick Start
First, wrap your whole app with the [`Web3Provider`](src/providers/Web3Provider) and the [`OceanProvider`](src/providers/OceanProvider). ### 1. Add Provider
### 1. Providers First, wrap your whole app with the [`<OceanProvider />`](src/providers/OceanProvider).
```tsx ### 2. Use Hooks
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 (
<Web3Provider>
<OceanProvider config={config}>
<h1>My App</h1>
{children}
</OceanProvider>
)}
</Web3Provider>
)
}
```
The `OceanProvider` requires a Web3 instance to be passed as prop so you can replace the basic [`Web3Provider`](src/providers/Web3Provider) with whatever component/library/provider returning a Web3 instance.
### 2. Hooks
Then within your component use the included hooks to interact with Ocean's functionality. Each hook can be used independently: Then within your component use the included hooks to interact with Ocean's functionality. Each hook can be used independently:
```tsx ```tsx
import React from 'react' import React from 'react'
import { import { useOcean, useMetadata, useConsume } from '@oceanprotocol/react'
useWeb3,
useOcean,
useMetadata,
useConsume
} from '@oceanprotocol/react'
const did = 'did:op:0x000000000' const did = 'did:op:0x000000000'
export default function MyComponent() { export default function MyComponent() {
// Get web3 from built-in Web3Provider context
const { web3 } = useWeb3()
// Get Ocean instance from built-in OceanProvider context // Get Ocean instance from built-in OceanProvider context
const { ocean, account } = useOcean() const { ocean, web3, account } = useOcean()
// Get metadata for this asset // Get metadata for this asset
const { title, metadata } = useMetadata(did) const { title, metadata } = useMetadata(did)

23
example/.gitignore vendored
View File

@ -1,23 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@ -0,0 +1,8 @@
# Example
Simple example app based on Create React App.
```bash
npm install
npm start
```

9078
example/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,22 +5,19 @@
"dependencies": { "dependencies": {
"-": "0.0.1", "-": "0.0.1",
"@oceanprotocol/react": "file:../", "@oceanprotocol/react": "file:../",
"@testing-library/jest-dom": "^4.2.4", "@toruslabs/torus-embed": "^1.8.2",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@toruslabs/torus-embed": "^1.7.3",
"@types/jest": "^24.9.1", "@types/jest": "^24.9.1",
"@types/node": "^12.12.47", "@types/node": "^12.12.47",
"@types/react": "^16.9.41", "@types/react": "^16.9.41",
"@types/react-dom": "^16.9.8", "@types/react-dom": "^16.9.8",
"@types/shortid": "0.0.29", "@types/shortid": "^0.0.29",
"@walletconnect/web3-provider": "^1.0.14", "@walletconnect/web3-provider": "^1.1.0",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"typescript": "^3.7.5", "typescript": "^3.9.7",
"web3-eth-contract": "^1.2.9" "web3-eth-contract": "^1.2.11"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
@ -31,16 +28,10 @@
"eslintConfig": { "eslintConfig": {
"extends": "react-app" "extends": "react-app"
}, },
"browserslist": { "browserslist": [
"production": [ ">0.2%",
">0.2%", "not dead",
"not dead", "not ie <= 11",
"not op_mini all" "not op_mini all"
], ]
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
} }

View File

@ -10,11 +10,6 @@
content="Web site created using create-react-app" content="Web site created using create-react-app"
/> />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build. It will be replaced with the URL of the `public` folder during the build.

View File

@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -7,25 +7,58 @@ import { Config, ConfigHelper } from '@oceanprotocol/lib'
import { AllDdos } from './AllDdos' import { AllDdos } from './AllDdos'
import { ConsumeDdo } from './ConsumeDdo' import { ConsumeDdo } from './ConsumeDdo'
import WalletConnectProvider from '@walletconnect/web3-provider'
import Torus from '@toruslabs/torus-embed'
// factory Address needs to be updated each time you deploy the contract on local network
const config = {
metadataStoreUri: 'http://aquarius:5000',
providerUri: 'http://localhost:8030',
nodeUri: `http://localhost:8545`,
factoryAddress: '0x2fC1fd21cb222Dc180Ef817dE4c426fd9230b5A5'
} as Config
const configRinkeby = {
metadataStoreUri: 'https://aquarius.rinkeby.v3.dev-ocean.com',
providerUri: 'https://provider.rinkeby.v3.dev-ocean.com',
nodeUri: `https://rinkeby.infura.io/a983b53583044593956054de049922fd`,
factoryAddress: '0xB9d406D24B310A7D821D0b782a36909e8c925471'
} as Config
const providerOptions = {
walletconnect: {
package: WalletConnectProvider,
options: {
infuraId: ''
}
},
torus: {
package: Torus,
options: {
networkParams: {
host: config.nodeUri // optional
// chainId: 1337, // optional
// networkId: 1337 // optional
}
}
}
}
export const web3ModalOpts = {
cacheProvider: true,
providerOptions
}
function App() { function App() {
// factory Address needs to be updated each time you deploy the contract on local network
const config = {
metadataStoreUri: 'http://aquarius:5000',
providerUri: 'http://localhost:8030',
nodeUri: `http://localhost:8545`,
factoryAddress: '0x2fC1fd21cb222Dc180Ef817dE4c426fd9230b5A5'
} as Config
const configRinkeby = new ConfigHelper().getConfig('rinkeby')
const init = async () => {} const init = async () => {}
useEffect(() => { useEffect(() => {
init() init()
}, []) }, [])
return ( return (
<div className="app"> <div className="app">
<OceanProvider config={configRinkeby}> <OceanProvider config={config} web3ModalOpts={web3ModalOpts}>
<div className="container"> <div className="container">
<div> <div>
<Wallet /> <Wallet />

View File

@ -3,29 +3,19 @@ import { useOcean } from '@oceanprotocol/react'
import { useEffect } from 'react' import { useEffect } from 'react'
export function Wallet() { export function Wallet() {
const { web3, ocean, connect, logout, accountId } = useOcean() const { ocean, connect, logout, accountId } = useOcean()
const conn = async () => {
const { default: WalletConnectProvider } = await import(
'@walletconnect/web3-provider'
)
const providerOptions = {
/* See Provider Options Section */
walletconnect: {
package: WalletConnectProvider, // required
options: {
infuraId: 'INFURA_ID' // required
}
}
}
await connect({ cacheProvider: true, providerOptions }) const conn = async () => {
await connect()
} }
const init = async () => { const init = async () => {
if (ocean === undefined || accountId === undefined) return if (ocean === undefined || accountId === undefined) return
const assets = await ocean.assets.ownerAssets(accountId) const assets = await ocean.assets.ownerAssets(accountId)
console.log(assets) console.log(assets)
} }
useEffect(() => { useEffect(() => {
init() init()
}, [ocean, accountId]) }, [ocean, accountId])
@ -34,6 +24,7 @@ export function Wallet() {
await logout() await logout()
await conn() await conn()
} }
return ( return (
<> <>
<div>wallet</div> <div>wallet</div>

80
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@oceanprotocol/react", "name": "@oceanprotocol/react",
"version": "0.0.28", "version": "0.0.30",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1627,13 +1627,13 @@
"dev": true "dev": true
}, },
"@types/react": { "@types/react": {
"version": "16.9.43", "version": "16.9.44",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.43.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.44.tgz",
"integrity": "sha512-PxshAFcnJqIWYpJbLPriClH53Z2WlJcVZE+NP2etUtWQs2s7yIMj3/LDKZT/5CHJ/F62iyjVCDu2H3jHEXIxSg==", "integrity": "sha512-BtLoJrXdW8DVZauKP+bY4Kmiq7ubcJq+H/aCpRfvPF7RAT3RwR73Sg8szdc2YasbAlWBDrQ6Q+AFM0KwtQY+WQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"csstype": "^2.2.0" "csstype": "^3.0.2"
} }
}, },
"@types/resolve": { "@types/resolve": {
@ -1663,12 +1663,12 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.7.1.tgz",
"integrity": "sha512-4OEcPON3QIx0ntsuiuFP/TkldmBGXf0uKxPQlGtS/W2F3ndYm8Vgdpj/woPJkzUc65gd3iR+qi3K8SDQP/obFg==", "integrity": "sha512-3DB9JDYkMrc8Au00rGFiJLK2Ja9CoMP6Ut0sHsXp3ZtSugjNxvSSHTnKLfo4o+QmjYBJqEznDqsG1zj4F2xnsg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/experimental-utils": "3.7.0", "@typescript-eslint/experimental-utils": "3.7.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"functional-red-black-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1",
"regexpp": "^3.0.0", "regexpp": "^3.0.0",
@ -1700,45 +1700,45 @@
} }
}, },
"@typescript-eslint/experimental-utils": { "@typescript-eslint/experimental-utils": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.7.1.tgz",
"integrity": "sha512-xpfXXAfZqhhqs5RPQBfAFrWDHoNxD5+sVB5A46TF58Bq1hRfVROrWHcQHHUM9aCBdy9+cwATcvCbRg8aIRbaHQ==", "integrity": "sha512-TqE97pv7HrqWcGJbLbZt1v59tcqsSVpWTOf1AqrWK7n8nok2sGgVtYRuGXeNeLw3wXlLEbY1MKP3saB2HsO/Ng==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.3", "@types/json-schema": "^7.0.3",
"@typescript-eslint/types": "3.7.0", "@typescript-eslint/types": "3.7.1",
"@typescript-eslint/typescript-estree": "3.7.0", "@typescript-eslint/typescript-estree": "3.7.1",
"eslint-scope": "^5.0.0", "eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0" "eslint-utils": "^2.0.0"
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.7.1.tgz",
"integrity": "sha512-2LZauVUt7jAWkcIW7djUc3kyW+fSarNEuM3RF2JdLHR9BfX/nDEnyA4/uWz0wseoWVZbDXDF7iF9Jc342flNqQ==", "integrity": "sha512-W4QV/gXvfIsccN8225784LNOorcm7ch68Fi3V4Wg7gmkWSQRKevO4RrRqWo6N/Z/myK1QAiGgeaXN57m+R/8iQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-visitor-keys": "^1.0.0", "@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "3.7.0", "@typescript-eslint/experimental-utils": "3.7.1",
"@typescript-eslint/types": "3.7.0", "@typescript-eslint/types": "3.7.1",
"@typescript-eslint/typescript-estree": "3.7.0", "@typescript-eslint/typescript-estree": "3.7.1",
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.7.1.tgz",
"integrity": "sha512-reCaK+hyKkKF+itoylAnLzFeNYAEktB0XVfSQvf0gcVgpz1l49Lt6Vo9x4MVCCxiDydA0iLAjTF/ODH0pbfnpg==", "integrity": "sha512-PZe8twm5Z4b61jt7GAQDor6KiMhgPgf4XmUb9zdrwTbgtC/Sj29gXP1dws9yEn4+aJeyXrjsD9XN7AWFhmnUfg==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.7.1.tgz",
"integrity": "sha512-xr5oobkYRebejlACGr1TJ0Z/r0a2/HUf0SXqPvlgUMwiMqOCu/J+/Dr9U3T0IxpE5oLFSkqMx1FE/dKaZ8KsOQ==", "integrity": "sha512-m97vNZkI08dunYOr2lVZOHoyfpqRs0KDpd6qkGaIcLGhQ2WPtgHOd/eVbsJZ0VYCQvupKrObAGTOvk3tfpybYA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "3.7.0", "@typescript-eslint/types": "3.7.1",
"@typescript-eslint/visitor-keys": "3.7.0", "@typescript-eslint/visitor-keys": "3.7.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"glob": "^7.1.6", "glob": "^7.1.6",
"is-glob": "^4.0.1", "is-glob": "^4.0.1",
@ -1771,9 +1771,9 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.7.1.tgz",
"integrity": "sha512-k5PiZdB4vklUpUX4NBncn5RBKty8G3ihTY+hqJsCdMuD0v4jofI5xuqwnVcWxfv6iTm2P/dfEa2wMUnsUY8ODw==", "integrity": "sha512-xn22sQbEya+Utj2IqJHGLA3i1jDzR43RzWupxojbSWnj3nnPLavaQmWe5utw03CwYao3r00qzXfgJMGNkrzrAA==",
"dev": true, "dev": true,
"requires": { "requires": {
"eslint-visitor-keys": "^1.1.0" "eslint-visitor-keys": "^1.1.0"
@ -3249,9 +3249,9 @@
} }
}, },
"csstype": { "csstype": {
"version": "2.6.11", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.11.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.2.tgz",
"integrity": "sha512-l8YyEC9NBkSm783PFTvh0FmJy7s5pFKrDp49ZL7zBGX3fWkO+N4EEyan1qqp8cwPLDcD0OSdyY6hAMoxp34JFw==", "integrity": "sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==",
"dev": true "dev": true
}, },
"d": { "d": {
@ -3684,9 +3684,9 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
}, },
"eslint": { "eslint": {
"version": "7.5.0", "version": "7.6.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.6.0.tgz",
"integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==", "integrity": "sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@ -4232,9 +4232,9 @@
"dev": true "dev": true
}, },
"eslint-plugin-react": { "eslint-plugin-react": {
"version": "7.20.3", "version": "7.20.5",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.5.tgz",
"integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", "integrity": "sha512-ajbJfHuFnpVNJjhyrfq+pH1C0gLc2y94OiCbAXT5O0J0YCKaFEHDV8+3+mDOr+w8WguRX+vSs1bM2BDG0VLvCw==",
"dev": true, "dev": true,
"requires": { "requires": {
"array-includes": "^3.1.1", "array-includes": "^3.1.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@oceanprotocol/react", "name": "@oceanprotocol/react",
"version": "0.0.28", "version": "0.0.30",
"description": "React hooks & components on top of @oceanprotocol/lib", "description": "React hooks & components on top of @oceanprotocol/lib",
"main": "dist/index.js", "main": "dist/index.js",
"umd:main": "dist/index.umd.js", "umd:main": "dist/index.umd.js",
@ -27,24 +27,23 @@
"dependencies": { "dependencies": {
"@oceanprotocol/lib": "^0.1.10", "@oceanprotocol/lib": "^0.1.10",
"axios": "^0.19.2", "axios": "^0.19.2",
"react": "^16.9.41",
"web3": "^1.2.11", "web3": "^1.2.11",
"web3modal": "^1.8.0" "web3modal": "^1.9.0"
}, },
"devDependencies": { "devDependencies": {
"@release-it/bumper": "^1.4.0", "@release-it/bumper": "^1.4.1",
"@types/react": "^16.9.41", "@types/react": "^16.9.43",
"@typescript-eslint/eslint-plugin": "^3.7.0", "@typescript-eslint/eslint-plugin": "^3.7.1",
"@typescript-eslint/parser": "^3.7.0", "@typescript-eslint/parser": "^3.7.1",
"auto-changelog": "^2.2.0", "auto-changelog": "^2.2.0",
"eslint": "^7.5.0", "eslint": "^7.5.0",
"eslint-config-oceanprotocol": "^1.5.0", "eslint-config-oceanprotocol": "^1.5.0",
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4", "eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.3", "eslint-plugin-react": "^7.20.5",
"microbundle": "^0.12.3", "microbundle": "^0.12.3",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"release-it": "^13.6.4", "release-it": "^13.6.6",
"typescript": "^3.9.7" "typescript": "^3.9.7"
}, },
"peerDependencies": { "peerDependencies": {

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 '../../utils'
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,110 +78,90 @@ 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() try {
Logger.log('Connecting ...')
const provider = await web3Modal.connect()
setWeb3Provider(provider)
const web3 = new Web3(provider)
setWeb3(web3)
Logger.log('Web3 created.', web3)
const chainId = web3 && (await web3.eth.getChainId())
setChainId(chainId)
Logger.log('chain id ', chainId)
config.web3Provider = web3
const ocean = await Ocean.getInstance(config)
setOcean(ocean)
Logger.log('Ocean instance created.', ocean)
setStatus(ProviderStatus.CONNECTED)
const account = (await ocean.accounts.list())[0]
setAccount(account)
Logger.log('Account ', account)
const accountId = await getAccountId(web3)
setAccountId(accountId)
Logger.log('account id', accountId)
const balance = await getBalance(account)
setBalance(balance)
Logger.log('balance', JSON.stringify(balance))
} catch (error) {
Logger.error(error)
} }
const instance = new Web3Modal(opts)
setWeb3Modal(instance)
Logger.log('Web3Modal instance created.', instance)
const provider = await instance.connect()
setWeb3Provider(provider)
const web3 = new Web3(provider)
setWeb3(web3)
Logger.log('Web3 created.', web3)
const chainId = web3 && (await web3.eth.getChainId())
setChainId(chainId)
Logger.log('chain id ', chainId)
config.web3Provider = web3
const ocean = await Ocean.getInstance(config)
setOcean(ocean)
Logger.log('Ocean instance created.', ocean)
setStatus(ProviderStatus.CONNECTED)
const account = (await ocean.accounts.list())[0]
setAccount(account)
Logger.log('Account ', account)
const accountId = await getAccountId(web3)
setAccountId(accountId)
Logger.log('account id', accountId)
const balance = await getBalance(account)
setBalance(balance)
Logger.log('balance', JSON.stringify(balance))
} }
async function logout() { async function logout() {
// ToDo check how is the proper way to logout // TODO: #67 check how is the proper way to logout
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
// //
const handleConnect = async (provider: any) => {
Logger.debug("Handling 'connect' event with payload", provider) // const handleConnect = async (provider: any) => {
} // Logger.debug("Handling 'connect' event with payload", provider)
// }
const handleAccountsChanged = async (accounts: string[]) => { const handleAccountsChanged = async (accounts: string[]) => {
console.debug("Handling 'accountsChanged' event with payload", accounts) Logger.debug("Handling 'accountsChanged' event with payload", accounts)
if (status === ProviderStatus.CONNECTED) { connect()
connect(web3ModalOpts)
}
// if (accounts.length > 0) {
// setAccountId(accounts[0])
// if (web3) {
// const balance = await getBalance(web3, accounts[0])
// setBalance(balance)
// }
// }
} }
// ToDo need to handle this, it's not implemented, need to update chainId and reinitialize ocean lib
const handleNetworkChanged = async (networkId: string | number) => { const handleNetworkChanged = async (networkId: string | number) => {
console.debug( Logger.debug(
"Handling 'networkChanged' event with payload", "Handling 'chainChanged' event with payload",
networkId, networkId,
status status
) )
if (status === ProviderStatus.CONNECTED) { connect()
connect(web3ModalOpts)
}
} }
// TODO: #68 Refetch balance periodically, or figure out some event to subscribe to
useEffect(() => { useEffect(() => {
web3Modal && web3Modal.on('connect', handleConnect) // web3Modal && web3Modal.on('connect', handleConnect)
if (web3Provider !== undefined && web3Provider !== null) { if (web3Provider !== undefined && web3Provider !== null) {
web3Provider.on('accountsChanged', handleAccountsChanged) web3Provider.on('accountsChanged', handleAccountsChanged)
web3Provider.on('networkChanged', handleNetworkChanged) web3Provider.on('chainChanged', handleNetworkChanged)
return () => { return () => {
web3Provider.removeListener('accountsChanged', handleAccountsChanged) web3Provider.removeListener('accountsChanged', handleAccountsChanged)
web3Provider.removeListener('networkChanged', handleNetworkChanged) web3Provider.removeListener('chainChanged', handleNetworkChanged)
} }
} }
}, [web3Modal, web3Provider]) }, [web3Modal, web3Provider])

View File

@ -2,11 +2,11 @@
The `OceanProvider` maintains a connection to the Ocean Protocol network in multiple steps: The `OceanProvider` maintains a connection to the Ocean Protocol network in multiple steps:
1. On mount, connect to Aquarius instance right away so any asset metadata can be retrieved before, and independent of any Web3 connections. 1. On mount, setup [Web3Modal](https://github.com/Web3Modal/).
2. Once Web3 becomes available, a connection to all Ocean Protocol network components is established. 2. Once connection with Web3Modal is started, Web3 becomes available.
3. Once Ocean becomes available, spits out some info about it. 3. Once Web3 becomes available, connection to Ocean Protocol components are initiated, all available under the `ocean` object.
Also provides a `useOcean` helper hook to access its context values from any component. With the included `useOcean` helper hook you can access all context values from any component.
## Usage ## Usage
@ -18,19 +18,23 @@ import { OceanProvider, Config } from '@oceanprotocol/react'
const config: Config = { const config: Config = {
nodeUri: '', nodeUri: '',
aquariusUri: '', metadataStoreUri: '',
... ...
} }
const web3ModalOpts = {
network: 'mainnet', // optional
cacheProvider: true, // optional
providerOptions // required
}
export default function MyApp({ export default function MyApp({
children children
}: { }: {
children: ReactNode children: ReactNode
}): ReactNode { }): ReactNode {
const web3 = await getWeb3()
return ( return (
<OceanProvider config={config} web3={web3}> <OceanProvider config={config} web3ModalOpts={web3ModalOpts}>
<h1>My App</h1> <h1>My App</h1>
{children} {children}
</OceanProvider> </OceanProvider>
@ -38,35 +42,7 @@ 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): The `OceanProvider` uses [Web3Modal](https://github.com/Web3Modal/) to make its initial wallet connection. If you do not pass `web3ModalOpts` as a prop, only the default injected provider will be available. Adding more providers requires you to add them as dependencies to your project and pass them as `providerOptions`. See all the available [Provider Options](https://github.com/Web3Modal/web3modal#provider-options).
```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 (
<Web3Provider>
{({ web3 }) => (
<OceanProvider config={config} web3={web3}>
<h1>My App</h1>
{children}
</OceanProvider>
)}
</Web3Provider>
)
}
```
You can then access the provider context values with the `useOcean` hook: You can then access the provider context values with the `useOcean` hook:
@ -74,12 +50,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

@ -25,3 +25,5 @@ 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 * from './web3'

15
src/utils/web3.ts Normal file
View File

@ -0,0 +1,15 @@
import Web3 from 'web3'
import { Account } from '@oceanprotocol/lib'
import { Balance } from '../providers'
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 }
}