-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Schwartz10/web3manager
Web3Manager
- Loading branch information
Showing
8 changed files
with
146 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,15 @@ | ||
import React, { Component } from 'react' | ||
import { connect } from 'react-redux'; | ||
import { fetchWeb3 } from './store/web3' | ||
import { fetchContract } from './store/contract' | ||
import { fetchAccounts } from './store/accounts'; | ||
import Routes from './components/Routes' | ||
import React from 'react' | ||
import Routes from './components/Routes'; | ||
|
||
import './css/oswald.css' | ||
import './css/open-sans.css' | ||
import './css/pure-min.css' | ||
import './App.css' | ||
|
||
class App extends Component { | ||
componentDidMount = () => this.collectBlockchainInfo(); | ||
const App = () => ( | ||
<div className="App"> | ||
<Routes /> | ||
</div> | ||
); | ||
|
||
collectBlockchainInfo = async () => { | ||
const { getContract, getAccounts } = this.props; | ||
// Get network provider, web3, and truffle contract instance and store them on state. | ||
const { web3 } = await this.props.getWeb3(); | ||
getContract(web3); | ||
getAccounts(web3); | ||
} | ||
|
||
render() { | ||
return ( | ||
<div className="App"> | ||
<Routes /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
function mapDispatchToProps(dispatch){ | ||
return { | ||
getWeb3: () => dispatch(fetchWeb3()), | ||
getContract: (web3) => dispatch(fetchContract(web3)), | ||
getAccounts: (web3) => dispatch(fetchAccounts(web3)) | ||
} | ||
} | ||
|
||
export default connect(null, mapDispatchToProps)(App); | ||
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
import React from 'react' | ||
import ReactDOM from 'react-dom' | ||
import App from './App' | ||
import {Provider} from 'react-redux' | ||
import { Provider } from 'react-redux' | ||
import store from './store' | ||
import Web3Manager from './web3/Web3Manager'; | ||
|
||
ReactDOM.render( | ||
<Provider store={store}> | ||
<App /> | ||
<div> | ||
<Web3Manager /> | ||
<App /> | ||
</div> | ||
</Provider>, | ||
document.getElementById('root') | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* INITIAL STATE | ||
*/ | ||
const defaultNetwork = false; | ||
|
||
/** | ||
* ACTION TYPES | ||
*/ | ||
const GET_NETWORK = 'GET_NETWORK'; | ||
|
||
/** | ||
* ACTION CREATORS | ||
*/ | ||
// receives true if the user is on a valid network, false if not | ||
export const setValidNetwork = bool => ({type: GET_NETWORK, bool}); | ||
|
||
/** | ||
* REDUCER | ||
*/ | ||
export default function (state = defaultNetwork, action) { | ||
switch (action.type) { | ||
case GET_NETWORK: | ||
return action.bool; | ||
default: | ||
return state | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React from 'react'; | ||
import Web3 from 'web3'; | ||
import { connect } from 'react-redux'; | ||
import { setWeb3 } from '../store/web3'; | ||
import { setAccount } from '../store/accounts'; | ||
import { setValidNetwork } from '../store/network'; | ||
|
||
const fetchWeb3 = (localProvider = null) => { | ||
let { web3 } = window; | ||
if (localProvider) { | ||
const provider = new Web3.providers.HttpProvider(localProvider) | ||
web3 = new Web3(provider) | ||
return web3; | ||
} | ||
else if (typeof web3 !== 'undefined') { | ||
// create new web3 instance with currentProvider | ||
web3 = new Web3(web3.currentProvider); | ||
return web3; | ||
} | ||
// if metamask did not inject web3 and we have no localProvider | ||
else { | ||
return null; | ||
} | ||
}; | ||
|
||
class Web3Manager extends React.Component { | ||
componentDidMount(){ | ||
// continuously look for updates to the window's web3 obj | ||
this.intervalId = setInterval(this.collectWeb3Data.bind(this), 500); | ||
} | ||
|
||
componentWillUnmount(){ | ||
// clears interval in case the component unmounts to avoid memory leaks | ||
clearInterval(this.intervalId); | ||
} | ||
|
||
collectWeb3Data() { | ||
// if any localProvider was passed in as prop, we use it to construct the web3 object | ||
const { localProvider, hasWeb3, currentAccount, validNetwork, requiredNetwork, | ||
setWeb3, setAccount, setValidNetwork } = this.props; | ||
const web3 = fetchWeb3(localProvider || null); | ||
|
||
/* -- we only dispatch actions if anything important CHANGED -- */ | ||
|
||
if (web3){ | ||
// dispatches an action if a web3 instance was recently created | ||
if (!hasWeb3) setWeb3(web3); | ||
|
||
// /* ---------- ensures the user is on the right network ----------- */ | ||
const currentNetworkId = Number(web3.version.network); | ||
|
||
// if component received a validNetwork prop, we make sure the user is on the valid network | ||
const onCorrectNetwork = requiredNetwork ? | ||
requiredNetwork === currentNetworkId : true; | ||
|
||
// valid network refers to the previous bool value kept on redux store | ||
const changedToValidNetwork = onCorrectNetwork && !validNetwork; | ||
|
||
if (changedToValidNetwork) setValidNetwork(true); | ||
|
||
/* ------------- checks for unlocked account change -------------- */ | ||
const [ account ] = web3.eth.accounts; | ||
const recentlyChangedAccount = account && account !== currentAccount; | ||
const recentlyLoggedOut = !account && currentAccount; | ||
|
||
// if an important account changed, dispatch the appropriate action | ||
if (recentlyChangedAccount || recentlyLoggedOut) { | ||
setAccount(account); | ||
} | ||
} | ||
} | ||
|
||
render(){ | ||
// this component does not need to render any JSX | ||
return(null); | ||
} | ||
} | ||
|
||
function mapStateToProps(state, props) { | ||
return { | ||
hasWeb3: Object.keys(state.web3).length > 0, | ||
validNetwork: state.network, | ||
currentAccount: state.account | ||
}; | ||
} | ||
|
||
export default connect( | ||
mapStateToProps, | ||
{ | ||
setWeb3, | ||
setAccount, | ||
setValidNetwork | ||
} | ||
)(Web3Manager); |