diff --git a/content/tutorials/react-get-use-data-set.md b/content/tutorials/react-get-use-data-set.md index 27f6cb69..43bbf12e 100644 --- a/content/tutorials/react-get-use-data-set.md +++ b/content/tutorials/react-get-use-data-set.md @@ -5,60 +5,81 @@ description: Tutorial to get and use a data set in a basic React app. ## Requirements -This is a continuation of the React App Tutorial. Make sure you already did the [React App Setup](/tutorials/react-setup/) and the [Publish a Data Set](/tutorials/react-publish-data-set/) steps. +This is a continuation of the React App Tutorial. Make sure you already did the previous steps: -Open `src/App.js` in your marketplace app. +1. [React App Setup](/tutorials/react-setup/) +2. [Publish a Data Set](/tutorials/react-publish-data-set/) + +Open `src/App.js` from your `marketplace/` folder. ## Retrieve Assets In the previous tutorial we added asset publishing. We can now search for published assets for consumption. Just after the `submitAsset()` function we can add a new function that will handle search: ```js +// src/App.js +// ... async retrieveAssets() { - this.dbAssets = await this.ocean.assets.search("10 Monkey Species Small") - console.log(this.dbAssets) + this.search = await this.ocean.assets.search('10 Monkey Species Small') + console.log(this.search) + alert( + 'Asset successfully retrieved. Look into your console to see the search response.' + ) } +// ... ``` -The last thing we need is a button to start our search inside the render function just after ``: +Now we need a button to start our search inside the render function just after ``: ```jsx +// src/App.js +// ... +// ... ``` ## Consume Assets -The retrieved assets can now be consumed so in this tutorial we consume the first one. The following code goes after the `async retrieveAssets()` function. +Consuming means downloading one or multiple files attached to an asset. During that process the initial `url` value we added during the publish process for each file will be decrpyted and the file can be downloaded. + +With the following code we start the consume process with the first search result, then go on to download its first attached file. Put it after the `retrieveAssets()` function: ```js +// src/App.js +// ... async consumeAsset() { // get all accounts const accounts = await this.ocean.accounts.list() // get first asset - const consumeAsset = this.dbAssets[0] + const consumeAsset = this.search.results[0] // get service we want to execute const service = consumeAsset.findServiceByType('Access') // order service agreement const agreement = await this.ocean.assets.order( - consumeAsset.id, - service.serviceDefinitionId, - accounts[0] + consumeAsset.id, + service.serviceDefinitionId, + accounts[0] ) // consume it await this.ocean.assets.consume( - agreement, - consumeAsset.id, - service.serviceDefinitionId, - accounts[0], - '' + agreement, + consumeAsset.id, + service.serviceDefinitionId, + accounts[0], + '', + 0 ) -} + } +// ... ``` We still need a button to start consumption. In the render function, just after the `` line, add: ```jsx +// src/App.js +// ... +// ... ``` With all these buttons in place, you should see this: @@ -69,87 +90,25 @@ Tip: Before clicking the `Retrieve assets` button, it might help to reload the p Go ahead and click the `Retrieve assets` button, and then the `Consume asset` button. Approve all the MetaMask dialog boxes. -If you have no errors in your `console.log` and can see your asset files listed, you have a working marketplace. +Have a look into `console.log` to see the various steps of the search and consume process. If you have no errors in your `console.log` and can see your asset files listed, you have a working marketplace. + +> Note: Consuming an asset will throw an error `Requested did is not found in the keeper network`. We are currently [investigating why that is happening](https://github.com/oceanprotocol/barge/issues/144) in either squid-js or Brizo and will remove this note once we verified a fix is in place in one of those components. ## Final Result Here is the full source of `src/App.js` that you should have if you followed this tutorial: ```jsx +// src/App.js import React, { Component } from 'react' import './App.css' import { Ocean } from '@oceanprotocol/squid' -import * as Web3 from 'web3' +import Web3 from 'web3' +import asset from './asset' const web3 = new Web3(window.web3.currentProvider) window.ethereum.enable() -const asset = { - base: { - name: '10 Monkey Species Small', - dateCreated: '2012-02-01T10:55:11Z', - author: 'Mario', - license: 'CC0: Public Domain', - contentType: 'jpg/txt', - price: 10, - files: [ - { - checksum: '2bf9d229d110d1976cdf85e9f3256c7f', - checksumType: 'MD5', - contentLength: 12057507, - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/training.zip' - }, - { - checksum: '354d19c0733c47ef3a6cce5b633116b0', - checksumType: 'MD5', - contentLength: 928, - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/monkey_labels.txt' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/validation.zip' - } - ], - checksum: '', - categories: ['image'], - tags: ['image data', 'classification', 'animals'], - type: 'dataset', - description: 'EXAMPLE ONLY ', - size: '3.1gb', - copyrightHolder: 'Unknown', - encoding: 'UTF-8', - compression: 'zip', - workExample: 'image path, id, label', - links: [ - { - name: 'example model', - url: - 'https://drive.google.com/open?id=1uuz50RGiAW8YxRcWeQVgQglZpyAebgSM' - }, - { - name: 'example code', - type: 'example code', - url: 'https://github.com/slothkong/CNN_classification_10_monkey_species' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/links/discovery/n5151.jpg', - name: 'n5151.jpg', - type: 'discovery' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/links/sample/sample.zip', - name: 'sample.zip', - type: 'sample' - } - ], - inLanguage: 'en' - } -} - class App extends Component { async componentDidMount() { this.ocean = await new Ocean.getInstance({ @@ -161,25 +120,32 @@ class App extends Component { parityUri: 'http://localhost:8545', secretStoreUri: 'http://localhost:12001' }) - console.log('Finished loading contracts!') + console.log('Finished loading contracts.') } async submitAsset() { const accounts = await this.ocean.accounts.list() const ddo = await this.ocean.assets.create(asset, accounts[0]) - alert('Asset successfully submitted: ', JSON.stringify(ddo)) + console.log('Asset successfully submitted.') + console.log(ddo) + alert( + 'Asset successfully submitted. Look into your console to see the response DDO object.' + ) } async retrieveAssets() { - this.dbAssets = await this.ocean.assets.search('10 Monkey Species Small') - console.log(this.dbAssets) + this.search = await this.ocean.assets.search('10 Monkey Species Small') + console.log(this.search) + alert( + 'Asset successfully retrieved. Look into your console to see the search response.' + ) } async consumeAsset() { // get all accounts const accounts = await this.ocean.accounts.list() // get first asset - const consumeAsset = this.dbAssets[0] + const consumeAsset = this.search.results[0] // get service we want to execute const service = consumeAsset.findServiceByType('Access') // order service agreement @@ -194,7 +160,8 @@ class App extends Component { consumeAsset.id, service.serviceDefinitionId, accounts[0], - '' + '', + 0 ) } @@ -203,6 +170,7 @@ class App extends Component {

Marketplace app

+
diff --git a/content/tutorials/react-publish-data-set.md b/content/tutorials/react-publish-data-set.md index 49736886..44b13438 100644 --- a/content/tutorials/react-publish-data-set.md +++ b/content/tutorials/react-publish-data-set.md @@ -7,15 +7,20 @@ description: Tutorial to add dataset publishing capabilities to a basic React ap This is a continuation of the [React App Setup](/tutorials/react-setup/) tutorial, so make sure you have done all the steps described in there. -Open `src/App.js` in your marketplace app from the [React App Setup](/tutorials/react-setup/) tutorial. +1. [React App Setup](/tutorials/react-setup/) + +Open `src/App.js` from your `marketplace/` folder. ## Define Asset First, let's add the [asset](/concepts/terminology/#asset-or-data-asset) that we want to publish. -To do that, we need to add the following code after `window.ethereum.enable()` line, defining our asset based on the [OEP-08](https://github.com/oceanprotocol/OEPs/tree/master/8) metadata structure: +To do that, we need to define the asset based on the [OEP-08](https://github.com/oceanprotocol/OEPs/tree/master/8) metadata structure. An asset can have multiple `files` attached to it and each file's `url` value will be encrypted during the publish process. To download that file later on, this value will be decrypted during the consume process. + +Let's create a new file `src/asset.js` and fill it with: ```js +// src/asset.js const asset = { base: { name: '10 Monkey Species Small', @@ -26,22 +31,28 @@ const asset = { price: 10, files: [ { + index: 0, + contentType: 'application/zip', checksum: '2bf9d229d110d1976cdf85e9f3256c7f', checksumType: 'MD5', contentLength: 12057507, + compression: 'zip', + encoding: 'UTF-8', url: 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/training.zip' }, { + index: 1, + contentType: 'text/txt', checksum: '354d19c0733c47ef3a6cce5b633116b0', checksumType: 'MD5', contentLength: 928, url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/monkey_labels.txt' + 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/monkey_labels.txt', + resourceId: 'test' }, { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/validation.zip' + index: 2 } ], checksum: '', @@ -49,10 +60,7 @@ const asset = { tags: ['image data', 'classification', 'animals'], type: 'dataset', description: 'EXAMPLE ONLY ', - size: '3.1gb', copyrightHolder: 'Unknown', - encoding: 'UTF-8', - compression: 'zip', workExample: 'image path, id, label', links: [ { @@ -81,111 +89,68 @@ const asset = { inLanguage: 'en' } } + +export default asset +``` + +Then import this asset definition at the top of `src/App.js`: + +```js +// src/App.js +// ... +import asset from './asset' +// ... ``` ## Handle Asset Publishing Now that we have an asset to submit, we need a function to handle it. Just before `render() {` let's add this function: -```js +```jsx +// src/App.js +// ... async submitAsset() { const accounts = await this.ocean.accounts.list() const ddo = await this.ocean.assets.create(asset, accounts[0]) - alert('Asset successfully submitted: ', JSON.stringify(ddo)) + console.log('Asset successfully submitted.') + console.log(ddo) + alert( + 'Asset successfully submitted. Look into your console to see the response DDO object.' + ) } +// ... ``` The last thing we need is a button to start our registration inside the render function just after `

Marketplace app

`: ```jsx +// src/App.js +// ... +// ... ``` Tip: Before clicking the `Register asset` button, it might help to reload the page. When you click on the `Register asset` button, you should get four separate dialog boxes from MetaMask, in a series, i.e. the second one only appears after you accept/approve the first one, and so on. -If you have no errors in your `console.log`, then you have successfully registered an asset. +Have a look into `console.log` to see the various steps of the register process. If you have no errors in your `console.log`, then you have successfully registered an asset. ## Final Result Here is the full source of `src/App.js` that you should have if you followed this tutorial: ```jsx +// src/App.js import React, { Component } from 'react' import './App.css' import { Ocean } from '@oceanprotocol/squid' -import * as Web3 from 'web3' +import Web3 from 'web3' +import asset from './asset' const web3 = new Web3(window.web3.currentProvider) window.ethereum.enable() -const asset = { - base: { - name: '10 Monkey Species Small', - dateCreated: '2012-02-01T10:55:11Z', - author: 'Mario', - license: 'CC0: Public Domain', - contentType: 'jpg/txt', - price: 10, - files: [ - { - checksum: '2bf9d229d110d1976cdf85e9f3256c7f', - checksumType: 'MD5', - contentLength: 12057507, - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/training.zip' - }, - { - checksum: '354d19c0733c47ef3a6cce5b633116b0', - checksumType: 'MD5', - contentLength: 928, - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/monkey_labels.txt' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/assets/validation.zip' - } - ], - checksum: '', - categories: ['image'], - tags: ['image data', 'classification', 'animals'], - type: 'dataset', - description: 'EXAMPLE ONLY ', - size: '3.1gb', - copyrightHolder: 'Unknown', - encoding: 'UTF-8', - compression: 'zip', - workExample: 'image path, id, label', - links: [ - { - name: 'example model', - url: - 'https://drive.google.com/open?id=1uuz50RGiAW8YxRcWeQVgQglZpyAebgSM' - }, - { - name: 'example code', - type: 'example code', - url: 'https://github.com/slothkong/CNN_classification_10_monkey_species' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/links/discovery/n5151.jpg', - name: 'n5151.jpg', - type: 'discovery' - }, - { - url: - 'https://s3.amazonaws.com/datacommons-seeding-us-east/10_Monkey_Species_Small/links/sample/sample.zip', - name: 'sample.zip', - type: 'sample' - } - ], - inLanguage: 'en' - } -} - class App extends Component { async componentDidMount() { this.ocean = await new Ocean.getInstance({ @@ -197,13 +162,17 @@ class App extends Component { parityUri: 'http://localhost:8545', secretStoreUri: 'http://localhost:12001' }) - console.log('Finished loading contracts!') + console.log('Finished loading contracts.') } async submitAsset() { const accounts = await this.ocean.accounts.list() const ddo = await this.ocean.assets.create(asset, accounts[0]) - alert('Asset successfully submitted: ', JSON.stringify(ddo)) + console.log('Asset successfully submitted.') + console.log(ddo) + alert( + 'Asset successfully submitted. Look into your console to see the response DDO object.' + ) } render() { diff --git a/content/tutorials/react-setup.md b/content/tutorials/react-setup.md index 47e13ddf..4280789b 100644 --- a/content/tutorials/react-setup.md +++ b/content/tutorials/react-setup.md @@ -7,20 +7,28 @@ description: This tutorial shows how you can build a basic [React](https://react - `Node.js` >= 10 is installed. You can check using `node -v` - `npm` >= 5.2 is installed. You can check using `npm -v` -- Git clone the [oceanprotocol/barge](https://github.com/oceanprotocol/barge) repository, then in that directory: +- [Docker](https://www.docker.com/products/docker-desktop) & [Docker Compose](https://docs.docker.com/compose/install/) +- A Web3 capable browser, like Firefox/Chrome with [MetaMask](https://metamask.io) installed +- `Spree`, a local Ocean test network - - (Optional) If you want to use Azure Storage or Amazon S3 storage, then go through the tutorials to set those up: [Azure](/tutorials/azure-for-brizo/) or [Amazon](/tutorials/amazon-s3-for-brizo/). Note that if you're using Azure Storage, you must edit the `barge/brizo.env` file and set all `AZURE_`... values. + - Git clone the [oceanprotocol/barge](https://github.com/oceanprotocol/barge) repository, then in that directory: - (Optional but recommended) Clean out all your old Docker stuff using `docker system prune --all --volumes` - - Use Barge to run a local Spree Testnet: + - Use the startup script in Barge to run a [local Spree Testnet](https://docs.oceanprotocol.com/concepts/testnets/#a-spree-testnet-for-local-development): ```bash - export KEEPER_VERSION=v0.9.1 - export AQUARIUS_VERSION=v0.2.2 - export BRIZO_VERSION=v0.3.5 - ./start_ocean.sh --latest --no-pleuston --local-spree-node + export KEEPER_VERSION=v0.9.1 && \ + export AQUARIUS_VERSION=v0.2.2 && \ + export BRIZO_VERSION=v0.3.5 && \ + ./start_ocean.sh --no-pleuston ``` -- Once your local Spree network is running, [get some Spree Ether](/tutorials/get-ether-and-ocean-tokens/#get-ether-for-a-local-spree-testnet) in a local account managed by MetaMask. + - Note that compiling and deploying the contracts in your local Docker network takes some time so it can take a few minutes until the network is ready to be interacted with. That usually is the case once `keeper-contracts_1` container doesn't show any messages anymore. + +- [Some `Spree` Ether](/tutorials/get-ether-and-ocean-tokens/#get-ether-for-a-local-spree-testnet) in your MetaMask account. You can execute this, replacing `` with your MetaMask account address: + + ```bash + curl --data '{"jsonrpc":"2.0","method":"personal_sendTransaction","params":[{"from":"0x00Bd138aBD70e2F00903268F3Db08f2D25677C9e","to":"","value":"0x7FFFFFFFFFFFFFFFFFF"}, "node0"],"id":0}' -H "Content-Type: application/json" -X POST localhost:8545 + ``` ## New Create React App @@ -30,11 +38,11 @@ First, kickstart your new React app by creating a boilerplate with Create React npx create-react-app marketplace ``` -This will create a folder named `marketplace` with a boilerplate React app. Go into that new folder and add the Ocean Protocol JavaScript library and Web3 packages to the app's dependencies: +This will create a folder named `marketplace` with a boilerplate React app. Go into that new folder and add the [Ocean Protocol JavaScript library](https://github.com/oceanprotocol/squid-js) to the app's dependencies: ```bash cd marketplace/ -npm install @oceanprotocol/squid@0.5.5 web3 +npm install @oceanprotocol/squid@0.5.6 ``` At this point you can already run `npm start` which starts the app in your browser at [localhost:3000](http://localhost:3000): @@ -46,6 +54,7 @@ At this point you can already run `npm start` which starts the app in your brows Let's make it ours, open `src/App.js` and replace the whole source with: ```jsx +// src/App.js import React, { Component } from 'react' import './App.css' @@ -65,8 +74,9 @@ export default App Below the `import './App.css'` line, let's import the packages we installed, set up web3 and unlock MetaMask accounts (if locked): ```js +// src/App.js import { Ocean } from '@oceanprotocol/squid' -import * as Web3 from 'web3' +import Web3 from 'web3' const web3 = new Web3(window.web3.currentProvider) window.ethereum.enable() @@ -77,7 +87,7 @@ After those steps you should see this, and MetaMask should have asked you to all ![React App 02](images/react-app-02.png) ![React App 03](images/react-app-03.png) -Note: If you see an error like `inpage.js:1 MetaMask - RPC Error: Internal JSON-RPC error.` in your `console.log`, don't worry about it. It's a MetaMask thing. +> Note: If you see an error like `inpage.js:1 MetaMask - RPC Error: Internal JSON-RPC error.` in your `console.log`, don't worry about it. It's a MetaMask thing. ## Create Ocean Instance @@ -86,18 +96,21 @@ Now that we are successfully connected with Web3, we can set up our Ocean instan At the beginning of your component (i.e. right after the `class App extends Component {` line), create a new Ocean instance with all configuration within the `componentDidMount` lifecycle method. All Ocean Protocol operations can be executed from this Ocean instance. ```js +// src/App.js +//... async componentDidMount() { this.ocean = await new Ocean.getInstance({ web3Provider: web3, - nodeUri: "http://localhost:8545", - aquariusUri: "http://localhost:5000", - brizoUri: "http://localhost:8030", - brizoAddress: "0x00bd138abd70e2f00903268f3db08f2d25677c9e", - parityUri: "http://localhost:8545", - secretStoreUri: "http://localhost:12001" + nodeUri: 'http://localhost:8545', + aquariusUri: 'http://localhost:5000', + brizoUri: 'http://localhost:8030', + brizoAddress: '0x00bd138abd70e2f00903268f3db08f2d25677c9e', + parityUri: 'http://localhost:8545', + secretStoreUri: 'http://localhost:12001' }) - console.log("Finished loading contracts!") + console.log('Finished loading contracts.') } +//... ``` ## Final Result @@ -109,10 +122,11 @@ That's it, if you have no errors in your `console.log` then you have successfull Here is the full source of `src/App.js` that you should have if you followed this tutorial: ```jsx +// src/App.js import React, { Component } from 'react' import './App.css' import { Ocean } from '@oceanprotocol/squid' -import * as Web3 from 'web3' +import Web3 from 'web3' const web3 = new Web3(window.web3.currentProvider) window.ethereum.enable() @@ -128,7 +142,7 @@ class App extends Component { parityUri: 'http://localhost:8545', secretStoreUri: 'http://localhost:12001' }) - console.log('Finished loading contracts!') + console.log('Finished loading contracts.') } render() { diff --git a/external/squid-js b/external/squid-js index 9545a95b..4432ecb4 160000 --- a/external/squid-js +++ b/external/squid-js @@ -1 +1 @@ -Subproject commit 9545a95b7f090ef195f67b65d94b3c77f8ec9e26 +Subproject commit 4432ecb4a635ec36eab264193c8cdfc805c77409