add update ERC20 account balance

add reselect - memoizes from the state tree
This commit is contained in:
Barry Gitarts 2018-06-05 13:19:21 -04:00
parent af17134f3e
commit cb41a904c5
5 changed files with 100 additions and 60 deletions

View File

@ -1,3 +1,4 @@
import ERC20Token from 'Embark/contracts/ERC20Token';
import { actions as accountActions } from '../reducers/accounts'
const { receiveAccounts } = accountActions
@ -7,7 +8,8 @@ export const fetchAndDispatchAccountsWithBalances = (web3, dispatch) => {
const defaultAccount = web3.eth.defaultAccount || addresses[0]
const accounts = addresses.map(async address => {
const balance = await web3.eth.getBalance(address, 'latest')
return { address, balance }
const ERC20TokenBalance = await ERC20Token.methods.balanceOf(address).call()
return { address, balance, ERC20TokenBalance }
})
Promise.all(accounts).then(accounts => {
dispatch(receiveAccounts(defaultAccount, accounts))

View File

@ -1,7 +1,9 @@
import EmbarkJS from 'Embark/EmbarkJS';
import ERC20Token from 'Embark/contracts/ERC20Token';
import React from 'react';
import { connect } from 'react-redux';
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
import { getCurrentAccount, accountsIsLoading } from '../reducers/accounts';
class ERC20TokenUI extends React.Component {
@ -67,59 +69,64 @@ class ERC20TokenUI extends React.Component {
console.log(txt);
}
render(){
return (<React.Fragment>
<h3> Read your account token balance </h3>
<Form inline>
<FormGroup>
<HelpBlock>Your test token balance is <span className="accountBalance">{this.state.accountBalance}</span></HelpBlock>
<Button bsStyle="primary" onClick={(e) => this.getDefaultAccountBalance()}>Get Balance</Button>
</FormGroup>
</Form>
<h3> Read account token balance</h3>
<Form inline>
<FormGroup>
<label>
Of:
<FormControl
type="text"
defaultValue={this.state.accountB}
onChange={(e) => this.balanceOf(e)} />
</label>
<label>
<HelpBlock><span className="balanceOf">{this.state.balanceOf}</span></HelpBlock>
</label>
</FormGroup>
</Form>
render() {
const { account, isLoading } = this.props;
return (
<React.Fragment>
<h3> Read your account token balance </h3>
<Form inline>
<FormGroup>
{!isLoading && <HelpBlock>Your test token balance is <span className="accountBalance">{account.ERC20TokenBalance}</span></HelpBlock>}
</FormGroup>
</Form>
<h3> Read account token balance</h3>
<Form inline>
<FormGroup>
<label>
Of:
<FormControl
type="text"
defaultValue={this.state.accountB}
onChange={(e) => this.balanceOf(e)} />
</label>
<label>
<HelpBlock><span className="balanceOf">{this.state.balanceOf}</span></HelpBlock>
</label>
</FormGroup>
</Form>
<h3> Transfer/Approve token balance</h3>
<Form inline>
<FormGroup>
<label>
To:
<FormControl
type="text"
defaultValue={this.state.transferTo}
onChange={(e) => this.update_transferTo(e) } />
</label>
<label>
Amount:
<FormControl
type="text"
defaultValue={this.state.transferAmount}
onChange={(e) => this.update_transferAmount(e) } />
</label>
<Button bsStyle="primary" onClick={(e) => this.transfer(e)}>Transfer</Button>
<Button bsStyle="primary" onClick={(e) => this.approve(e)}>Approve</Button>
</FormGroup>
</Form>
<h3> Transfer/Approve token balance</h3>
<Form inline>
<FormGroup>
<label>
To:
<FormControl
type="text"
defaultValue={this.state.transferTo}
onChange={(e) => this.update_transferTo(e) } />
</label>
<label>
Amount:
<FormControl
type="text"
defaultValue={this.state.transferAmount}
onChange={(e) => this.update_transferAmount(e) } />
</label>
<Button bsStyle="primary" onClick={(e) => this.transfer(e)}>Transfer</Button>
<Button bsStyle="primary" onClick={(e) => this.approve(e)}>Approve</Button>
</FormGroup>
</Form>
</React.Fragment>
);
}
);
}
}
export default ERC20TokenUI;
const mapStateToProps = state => ({
account: getCurrentAccount(state),
isLoading: accountsIsLoading(state),
});
export default connect(mapStateToProps)(ERC20TokenUI);

View File

@ -3,6 +3,8 @@ import TestToken from 'Embark/contracts/TestToken';
import React from 'react';
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
import ERC20TokenUI from './erc20token';
import { connect } from 'react-redux';
import { actions as accountActions } from '../reducers/accounts';
class TestTokenUI extends React.Component {
@ -17,15 +19,18 @@ class TestTokenUI extends React.Component {
this.setState({amountToMint: e.target.value});
}
mint(e){
mint(e){
const { addToBalance } = this.props;
e.preventDefault();
var value = parseInt(this.state.amountToMint, 10);
if (EmbarkJS.isNewWeb3()) {
TestToken.methods.mint(value).send({from: web3.eth.defaultAccount});
TestToken.methods.mint(value).send({from: web3.eth.defaultAccount})
.then(r => { addToBalance(value) });
} else {
TestToken.mint(value);
TestToken.mint(value).send({from: web3.eth.defaultAccount})
.then(r => { addToBalance(value) });
}
console.log(TestToken.options.address +".mint("+value+").send({from: " + web3.eth.defaultAccount + "})");
}
@ -50,4 +55,10 @@ class TestTokenUI extends React.Component {
}
}
export default TestTokenUI;
const mapDispatchToProps = dispatch => ({
addToBalance(amount) {
dispatch(accountActions.addToErc20TokenBalance(amount));
},
});
export default connect(null, mapDispatchToProps)(TestTokenUI);

View File

@ -1,12 +1,15 @@
import { createTypes, actionCreator } from 'redux-action-creator'
import { createSelector } from 'reselect'
export const types = createTypes([
'RECEIVE_ACCOUNTS',
'UPDATE_DEFAULT_ACCOUNT'
'UPDATE_DEFAULT_ACCOUNT',
'ADD_TO_ERC20_TOKEN_BALANCE'
], 'ACCOUNTS')
export const actions = {
receiveAccounts: actionCreator(types.RECEIVE_ACCOUNTS, 'defaultAccount','accounts'),
updateDefaultAccount: actionCreator(types.UPDATE_DEFAULT_ACCOUNT, 'defaultAccount')
updateDefaultAccount: actionCreator(types.UPDATE_DEFAULT_ACCOUNT, 'defaultAccount'),
addToErc20TokenBalance: actionCreator(types.ADD_TO_ERC20_TOKEN_BALANCE, 'amount')
}
export default function(state = { loading: true, accounts: [] }, action) {
@ -24,6 +27,17 @@ export default function(state = { loading: true, accounts: [] }, action) {
const { defaultAccount } = action.payload
return { ...state, defaultAccount }
}
case types.ADD_TO_ERC20_TOKEN_BALANCE: {
const currentAccount = { ...getCurrentAccount({accounts: state}) }
currentAccount.ERC20TokenBalance = Number(currentAccount.ERC20TokenBalance) + Number(action.payload.amount)
const accounts = [ ...state.accounts ]
const idx = accounts.findIndex(a => a.address === currentAccount.address)
accounts[idx] = currentAccount
return {
...state,
accounts
}
}
default:
return state;
}
@ -33,3 +47,8 @@ export const getAccountState = state => state.acounts;
export const getAccounts = state => state.accounts.accounts;
export const getDefaultAccount = state => state.accounts.defaultAccount;
export const accountsIsLoading = state => state.accounts.loading;
export const getCurrentAccount = createSelector(
getDefaultAccount,
getAccounts,
(defaultAccount, accounts) => accounts.find(a => a.address === defaultAccount)
)

View File

@ -26,7 +26,8 @@
"react-redux": "^5.0.7",
"redux": "^4.0.0",
"redux-action-creator": "^2.3.0",
"redux-thunk": "^2.3.0"
"redux-thunk": "^2.3.0",
"reselect": "^3.0.1"
},
"devDependencies": {
"babel-plugin-transform-object-rest-spread": "^6.26.0",