diff --git a/demo/client/.env b/demo/client/.env index cd53da4a..74d895b5 100644 --- a/demo/client/.env +++ b/demo/client/.env @@ -6,6 +6,7 @@ REACT_APP_ENABLE_SERVICE_DATA_STORE=false # Online Safety # To comply with rules and laws regarding what can be shown, you can enable this setting to be very strict # and hide text and images that are user generated except for items you have explicitly allowed. -# TODO Say where to configure allowed list. +# Configure in: client/src/safety/config.ts + # Default is disabled. REACT_APP_ENABLE_ONLINE_SAFETY=true diff --git a/demo/client/migrations/2_deploy_sentiment_classifier.js b/demo/client/migrations/2_deploy_sentiment_classifier.js index 36d2463d..7ff2a91a 100644 --- a/demo/client/migrations/2_deploy_sentiment_classifier.js +++ b/demo/client/migrations/2_deploy_sentiment_classifier.js @@ -13,7 +13,7 @@ module.exports = async function (deployer) { if (deployer.network === 'skipMigrations') { return; } - // Information to persist to the DB. + // Information to persist to the database. const name = "IMDB Review Sentiment Classifier" const description = "A simple IMDB sentiment analysis model." const encoder = 'IMDB vocab' @@ -81,11 +81,11 @@ module.exports = async function (deployer) { ]).then(() => { modelInfo.address = instance.address; return axios.post(`${pjson.proxy}api/models`, modelInfo).then(() => { - console.log("Added model to DB."); + console.log("Added model to the database."); }).catch(err => { if (process.env.CI !== "true" && process.env.REACT_APP_ENABLE_SERVICE_DATA_STORE === 'true') { // It is okay to fail adding the model in CI but otherwise it should work. - console.error("Error adding model to DB."); + console.error("Error adding model to the database."); console.error(err); throw err; } diff --git a/demo/client/migrations/3_deploy_VPA_classifier.js b/demo/client/migrations/3_deploy_VPA_classifier.js index 6bc231e0..3525e565 100644 --- a/demo/client/migrations/3_deploy_VPA_classifier.js +++ b/demo/client/migrations/3_deploy_VPA_classifier.js @@ -13,7 +13,7 @@ module.exports = function (deployer) { if (deployer.network === 'skipMigrations') { return; } - // Information to persist to the DB. + // Information to persist to the database. const name = "VPA Classifier" const description = "Supports multiple domains." const encoder = 'universal sentence encoder' @@ -83,10 +83,10 @@ module.exports = function (deployer) { ].concat(addClassPromises)).then(() => { modelInfo.address = instance.address; return axios.post(`${pjson.proxy}api/models`, modelInfo).then(() => { - console.log("Added model to DB."); + console.log("Added model to the database."); }).catch(err => { if (process.env.CI !== "true" && process.env.REACT_APP_ENABLE_SERVICE_DATA_STORE === 'true') { - console.error("Error adding model to DB."); + console.error("Error adding model to the database."); console.error(err); throw err; } diff --git a/demo/client/migrations/4_deploy_hot_dog_classifier.js b/demo/client/migrations/4_deploy_hot_dog_classifier.js index 93a1a5f5..d64e55b7 100644 --- a/demo/client/migrations/4_deploy_hot_dog_classifier.js +++ b/demo/client/migrations/4_deploy_hot_dog_classifier.js @@ -15,7 +15,7 @@ module.exports = function (deployer) { } const toFloat = 1E9; - // Information to persist to the DB. + // Information to persist to the database. const name = "Hot Dog Classifier" const description = "Classifies pictures as hot dog or not hot dog." const encoder = 'MobileNetv2' @@ -94,10 +94,10 @@ module.exports = function (deployer) { modelInfo.address = instance.address; return axios.post(`${pjson.proxy}api/models`, modelInfo).then(() => { - console.log("Added model to DB."); + console.log("Added model to the database."); }).catch(err => { if (process.env.CI !== "true" && process.env.REACT_APP_ENABLE_SERVICE_DATA_STORE === 'true') { - console.error("Error adding model to DB."); + console.error("Error adding model to the database."); console.error(err); throw err; } diff --git a/demo/client/src/components/model.js b/demo/client/src/components/model.js index 42ba9d0f..6e1064b0 100644 --- a/demo/client/src/components/model.js +++ b/demo/client/src/components/model.js @@ -33,7 +33,7 @@ import CollaborativeTrainer from '../contracts/CollaborativeTrainer64.json'; import DataHandler from '../contracts/DataHandler64.json'; import IncentiveMechanism from '../contracts/Stakeable64.json'; import ImdbVocab from '../data/imdb.json'; -import { getWeb3 } from '../getWeb3'; +import { getNetworkType, getWeb3 } from '../getWeb3'; import { OnlineSafetyValidator } from '../safety/validator'; import { OriginalData } from '../storage/data-store'; import { DataStoreFactory } from '../storage/data-store-factory'; @@ -198,8 +198,7 @@ class Model extends React.Component { }); } catch (error) { console.error(error); - // TODO Toast error. - alert(`Failed to load web3, accounts, or contract. Check console for details.`); + this.notify("Failed to load web3, accounts, or contract. Check console for details.", { variant: 'error' }) } } @@ -228,7 +227,7 @@ class Model extends React.Component { { const validator = new OnlineSafetyValidator(this.web3) - const networkType = await this.web3.eth.net.getNetworkType() + const networkType = await getNetworkType() this.setState({ checkedContentRestriction: true, restrictContent: !validator.isPermitted(networkType, contractAddress) @@ -881,8 +880,7 @@ class Model extends React.Component { return this.state.contractInstance.methods.addData(trainData, classification) .send({ from: this.state.accounts[0], value }) .on('transactionHash', (transactionHash) => { - // TODO Pop up confirmation that data was sent. - // console.log(`Data sent. status:${status}\nevents:`); + this.notify("Data was sent but has not been confirmed yet") // Save original training data. // We don't really need to save it to the blockchain @@ -897,23 +895,21 @@ class Model extends React.Component { if (this.state.storageType !== 'none') { const storage = this.storages[this.state.storageType]; return storage.saveOriginalData(transactionHash, new OriginalData(originalData)).then(() => { - // TODO Toast. - console.log("Saved info to DB.") + this.notify("Saved info to database.") return this.updateRefundData().then(this.updateDynamicInfo); }).catch(err => { - // TODO Toast. - console.error("Error saving original data to DB."); + this.notify("Error saving original data to the database.", { variant: 'error' }) + console.error("Error saving original data to the database."); console.error(err); }); } }) - .on('receipt', (receipt) => { + .on('receipt', (_receipt) => { // Doesn't get triggered through promise after updating to `web3 1.0.0-beta.52`. + // Some helpful fields: // const { events, /* status */ } = receipt; - // console.log(events); // const vals = events.AddData.returnValues; - const { transactionHash } = receipt; - console.log(`transactionHash: ${transactionHash}`); + // const { transactionHash } = receipt; }) .on('error', err => { console.error(err); diff --git a/demo/client/src/containers/modelList.js b/demo/client/src/containers/modelList.js index 6f7e0e6b..f9312f85 100644 --- a/demo/client/src/containers/modelList.js +++ b/demo/client/src/containers/modelList.js @@ -17,7 +17,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import update from 'react-addons-update'; import { checkStorages } from '../components/storageSelector'; -import { getWeb3 } from '../getWeb3'; +import { getNetworkType } from '../getWeb3'; import { OnlineSafetyValidator } from '../safety/validator'; import { DataStoreFactory } from '../storage/data-store-factory'; @@ -74,9 +74,9 @@ class ModelList extends React.Component { } componentDidMount = async () => { - const web3 = await getWeb3() this.validator = new OnlineSafetyValidator() - this.networkType = await web3.eth.net.getNetworkType() + this.networkType = await getNetworkType() + checkStorages(this.storages).then(permittedStorageTypes => { permittedStorageTypes = permittedStorageTypes.filter(storageType => storageType !== undefined) this.setState({ permittedStorageTypes }, this.updateModels) diff --git a/demo/client/src/getWeb3.js b/demo/client/src/getWeb3.js index bdb33cec..5a2c755c 100644 --- a/demo/client/src/getWeb3.js +++ b/demo/client/src/getWeb3.js @@ -6,8 +6,21 @@ export async function getWeb3() { // Get rid of a warning about network refreshing. window.ethereum.autoRefreshOnNetworkChange = false } - // TODO Fallback to Ethereum mainnet. - const fallbackProvider = new Web3.providers.HttpProvider("http://127.0.0.1:7545") + // Fallback to Ethereum mainnet. + // Address copied from MetaMask. + const fallbackProvider = new Web3.providers.HttpProvider("https://api.infura.io/v1/jsonrpc/mainnet") const result = await _getWeb3({ fallbackProvider, requestPermission: true }) return result } + +export async function getNetworkType() { + return _getWeb3().then(web3 => { + return web3.eth.net.getNetworkType() + }).catch(err => { + console.warn("Error getting the network type.") + console.warn(err) + alert("Could not find an Ethereum wallet provider so mainnet will be used") + // Assume mainnet + return 'main' + }) +}