From fc61811104f0312e4c735cabc3c4c2d3744b436c Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Wed, 4 Mar 2020 13:45:54 +0100 Subject: [PATCH] Feature: replace web3connect with onboardjs (#456) * init onboard.js * dep bump * initial replacement of web3connect with onboard.js * use averta font in the modal * update onboard.js, add handlers for session murder * update preferred wallets * implement reconnecting to injected provider * fix duplicate wallet disconnected notification * update onboard dep * onboardjs fixes * test onboard js with hw * add https to rpcUrl * Added saved wallet and transactions validation * made Transactions validation * bnc-onboard version updated * Fix lock/unlock problem * bump onboardjs version * fixed material-ui lab version * Update onboard version * Added hw wallets integration * Updated preferred wallets * Add ledger modal * Merge with dev * Update onboard * BUmp new version of onboardjs * Added some logs * Added some logs * Update onboardjs version fix ledger connection * Update onboardjs version fix ledger connection * Bump new onboardjs version * Update new version * Made improvements * yarn.lock regenration * remove https=true * Remove comments and added some improvements * Updated package.json dep * Removed unused deps * Remove web3connect dep Co-authored-by: lukasschor Co-authored-by: Mati Dastugue --- package.json | 85 +- .../dataDisplay/IconText/index.js | 2 +- src/components/ConnectButton/index.jsx | 133 +- src/components/Header/index.jsx | 9 +- .../wallets/store/actions/fetchProvider.js | 7 +- .../wallets/store/actions/removeProvider.js | 17 +- .../store/middlewares/providerWatcher.js | 5 +- .../Transactions/TxsTable/TxType/index.jsx | 13 +- .../safe/store/actions/createTransaction.js | 4 + yarn.lock | 2351 ++++++++--------- 10 files changed, 1216 insertions(+), 1410 deletions(-) diff --git a/package.json b/package.json index 6487e9bb5c..33defce2e2 100644 --- a/package.json +++ b/package.json @@ -46,21 +46,17 @@ "@material-ui/core": "4.8.0", "@material-ui/icons": "4.5.1", "@material-ui/lab": "4.0.0-alpha.39", - "@portis/web3": "^2.0.0-beta.45", - "@testing-library/jest-dom": "4.2.4", - "@toruslabs/torus-embed": "0.2.10", - "@walletconnect/web3-provider": "^1.0.0-beta.37", + "@testing-library/jest-dom": "5.0.0", "@welldone-software/why-did-you-render": "3.4.1", - "authereum": "^0.0.4-beta.83", "axios": "0.19.0", "bignumber.js": "9.0.0", + "bnc-onboard": "1.3.0", "connected-react-router": "6.6.1", "currency-flags": "^2.1.1", - "date-fns": "2.8.1", + "date-fns": "2.9.0", "dotenv": "^8.2.0", "ethereum-ens": "0.8.0", "final-form": "4.18.6", - "fortmatic": "^1.0.1", "history": "4.10.1", "immortal-db": "^1.0.2", "immutable": "^4.0.0-rc.9", @@ -71,7 +67,7 @@ "optimize-css-assets-webpack-plugin": "5.0.3", "polished": "^3.4.2", "qrcode.react": "1.0.0", - "query-string": "6.9.0", + "query-string": "6.10.1", "react": "16.12.0", "react-dev-utils": "^10.0.0", "react-dom": "16.12.0", @@ -84,42 +80,41 @@ "react-router-dom": "5.1.2", "react-window": "^1.8.5", "recompose": "^0.30.0", - "redux": "4.0.4", + "redux": "4.0.5", "redux-actions": "^2.6.5", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", "semver": "^7.1.1", "styled-components": "^5.0.1", - "web3": "1.2.4", - "web3connect": "1.0.0-beta.25" + "web3": "1.2.4" }, "devDependencies": { - "@babel/cli": "7.7.5", - "@babel/core": "7.7.5", - "@babel/plugin-proposal-class-properties": "7.7.4", - "@babel/plugin-proposal-decorators": "7.7.4", - "@babel/plugin-proposal-do-expressions": "7.7.4", - "@babel/plugin-proposal-export-default-from": "7.7.4", - "@babel/plugin-proposal-export-namespace-from": "7.7.4", - "@babel/plugin-proposal-function-bind": "7.7.4", - "@babel/plugin-proposal-function-sent": "7.7.4", - "@babel/plugin-proposal-json-strings": "7.7.4", - "@babel/plugin-proposal-logical-assignment-operators": "7.7.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.7.4", - "@babel/plugin-proposal-numeric-separator": "7.7.4", - "@babel/plugin-proposal-optional-chaining": "7.7.5", - "@babel/plugin-proposal-pipeline-operator": "7.7.4", - "@babel/plugin-proposal-throw-expressions": "7.7.4", - "@babel/plugin-syntax-dynamic-import": "7.7.4", - "@babel/plugin-syntax-import-meta": "7.7.4", - "@babel/plugin-transform-member-expression-literals": "7.7.4", - "@babel/plugin-transform-property-literals": "7.7.4", - "@babel/polyfill": "7.7.0", - "@babel/preset-env": "7.7.6", - "@babel/preset-flow": "7.7.4", - "@babel/preset-react": "7.7.4", + "@babel/cli": "7.8.3", + "@babel/core": "7.8.3", + "@babel/plugin-proposal-class-properties": "7.8.3", + "@babel/plugin-proposal-decorators": "7.8.3", + "@babel/plugin-proposal-do-expressions": "7.8.3", + "@babel/plugin-proposal-export-default-from": "7.8.3", + "@babel/plugin-proposal-export-namespace-from": "7.8.3", + "@babel/plugin-proposal-function-bind": "7.8.3", + "@babel/plugin-proposal-function-sent": "7.8.3", + "@babel/plugin-proposal-json-strings": "7.8.3", + "@babel/plugin-proposal-logical-assignment-operators": "7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3", + "@babel/plugin-proposal-numeric-separator": "7.8.3", + "@babel/plugin-proposal-optional-chaining": "7.8.3", + "@babel/plugin-proposal-pipeline-operator": "7.8.3", + "@babel/plugin-proposal-throw-expressions": "7.8.3", + "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/plugin-syntax-import-meta": "7.8.3", + "@babel/plugin-transform-member-expression-literals": "7.8.3", + "@babel/plugin-transform-property-literals": "7.8.3", + "@babel/polyfill": "7.8.3", + "@babel/preset-env": "7.8.3", + "@babel/preset-flow": "7.8.3", + "@babel/preset-react": "7.8.3", "@testing-library/react": "9.4.0", - "autoprefixer": "9.7.3", + "autoprefixer": "9.7.4", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "10.0.3", "babel-jest": "24.9.0", @@ -129,7 +124,7 @@ "babel-plugin-transform-es3-property-literals": "^6.22.0", "babel-polyfill": "^6.26.0", "classnames": "^2.2.6", - "css-loader": "3.4.0", + "css-loader": "3.4.2", "detect-port": "^1.3.0", "dotenv-expand": "^5.1.0", "eslint": "^6.8.0", @@ -143,7 +138,7 @@ "ethereumjs-abi": "0.6.8", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "5.0.2", - "flow-bin": "0.114.0", + "flow-bin": "0.116.1", "fs-extra": "8.1.0", "html-loader": "^0.5.5", "html-webpack-plugin": "^3.2.0", @@ -151,22 +146,22 @@ "jest": "24.9.0", "jest-dom": "4.0.0", "json-loader": "^0.5.7", - "mini-css-extract-plugin": "0.8.1", + "mini-css-extract-plugin": "0.9.0", "postcss-loader": "^3.0.0", "postcss-mixins": "6.2.3", "postcss-simple-vars": "^5.0.2", "prettier": "^1.19.1", "run-with-testrpc": "0.3.1", - "style-loader": "1.0.2", - "terser-webpack-plugin": "2.3.1", - "truffle": "5.1.4", + "style-loader": "1.1.3", + "terser-webpack-plugin": "2.3.2", + "truffle": "5.1.9", "truffle-contract": "4.0.31", "truffle-solidity-loader": "0.1.32", "url-loader": "3.0.0", - "webpack": "4.41.3", + "webpack": "4.41.5", "webpack-bundle-analyzer": "3.6.0", "webpack-cli": "3.3.10", - "webpack-dev-server": "3.9.0", + "webpack-dev-server": "3.10.1", "webpack-manifest-plugin": "2.2.0" } -} +} \ No newline at end of file diff --git a/src/components-v2/dataDisplay/IconText/index.js b/src/components-v2/dataDisplay/IconText/index.js index 9206003d68..f2e8ded27a 100644 --- a/src/components-v2/dataDisplay/IconText/index.js +++ b/src/components-v2/dataDisplay/IconText/index.js @@ -17,7 +17,7 @@ const Text = styled.span` const IconText = ({ iconUrl, text }: { iconUrl: string, text: string }) => ( - + {text} ) diff --git a/src/components/ConnectButton/index.jsx b/src/components/ConnectButton/index.jsx index b0c6673255..72dfd6d690 100644 --- a/src/components/ConnectButton/index.jsx +++ b/src/components/ConnectButton/index.jsx @@ -1,69 +1,99 @@ // @flow -import Portis from '@portis/web3' -import Torus from '@toruslabs/torus-embed' -import WalletConnectProvider from '@walletconnect/web3-provider' -import Authereum from 'authereum' -import Fortmatic from 'fortmatic' +import Onboard from 'bnc-onboard' import React from 'react' -import Web3Connect from 'web3connect' import Button from '~/components/layout/Button' -import { getNetwork } from '~/config' -import { fetchProvider, removeProvider } from '~/logic/wallets/store/actions' +import { getNetworkId } from '~/config' +import { getWeb3, setWeb3 } from '~/logic/wallets/getWeb3' +import { fetchProvider } from '~/logic/wallets/store/actions' +import transactionDataCheck from '~/logic/wallets/transactionDataCheck' import { store } from '~/store' const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' +const BLOCKNATIVE_API_KEY = isMainnet ? process.env.REACT_APP_BLOCKNATIVE_KEY : '7fbb9cee-7e97-4436-8770-8b29a9a8814c' const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f28b-4463-80cb-846d7ec5806b' // const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78' const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40' -export const web3Connect = new Web3Connect.Core({ - network: getNetwork().toLowerCase(), - providerOptions: { - walletconnect: { - package: WalletConnectProvider, - options: { - infuraId: process.env.REACT_APP_INFURA_TOKEN, - }, - }, - portis: { - package: Portis, - options: { - id: PORTIS_DAPP_ID, - }, - }, - fortmatic: { - package: Fortmatic, - options: { - key: FORTMATIC_API_KEY, - }, - }, - torus: { - package: Torus, - options: { - enableLogging: false, - buttonPosition: 'bottom-left', - buildEnv: process.env.NODE_ENV, - showTorusButton: true, - }, +const wallets = [ + { walletName: 'metamask', preferred: true }, + { + walletName: 'walletConnect', + preferred: true, + infuraKey: process.env.REACT_APP_INFURA_TOKEN, + }, + { + walletName: 'trezor', + appUrl: 'gnosis-safe.io', + preferred: true, + email: 'safe@gnosis.io', + rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba', + }, + { + walletName: 'ledger', + preferred: true, + rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba', + }, + { walletName: 'trust', preferred: true }, + { walletName: 'dapper' }, + { + walletName: 'fortmatic', + apiKey: FORTMATIC_API_KEY, + }, + { + walletName: 'portis', + apiKey: PORTIS_DAPP_ID, + label: 'Login with Email', + }, + { walletName: 'authereum' }, + { walletName: 'coinbase' }, + { walletName: 'opera' }, + { walletName: 'operaTouch' }, +] + +let lastUsedAddress = '' +let providerName + +export const onboard = new Onboard({ + dappId: BLOCKNATIVE_API_KEY, + networkId: getNetworkId(), + subscriptions: { + wallet: wallet => { + if (wallet.provider) { + // this function will intialize web3 and store it somewhere available throughout the dapp and + // can also instantiate your contracts with the web3 instance + setWeb3(wallet.provider) + providerName = wallet.name + } }, - authereum: { - package: Authereum, - options: {}, + address: address => { + if (!lastUsedAddress && address) { + lastUsedAddress = address + store.dispatch(fetchProvider(providerName)) + } + + // we don't have an unsubscribe event so we rely on this + if (!address && lastUsedAddress) { + lastUsedAddress = '' + providerName = undefined + } }, }, + walletSelect: { + wallets, + }, + walletCheck: [{ checkName: 'connect' }, transactionDataCheck(), { checkName: 'network' }, { checkName: 'accounts' }], }) -web3Connect.on('connect', (provider: any) => { - if (provider) { - store.dispatch(fetchProvider(provider)) - } -}) - -web3Connect.on('disconnect', () => { - store.dispatch(removeProvider()) -}) +export const onboardUser = async () => { + // before calling walletSelect you want to check if web3 has been instantiated + // which indicates that a wallet has already been selected + // and web3 has been instantiated with that provider + const web3 = getWeb3() + const walletSelected = web3 ? true : await onboard.walletSelect() + return walletSelected && onboard.walletCheck() +} type Props = { enqueueSnackbar: Function, @@ -74,8 +104,9 @@ const ConnectButton = (props: Props) => (