Adding balance in eth and creation of identities

This commit is contained in:
Richard Ramos 2018-08-06 13:47:56 -04:00
parent bd93bb3062
commit 1262299e77
11 changed files with 399 additions and 58 deletions

View File

@ -0,0 +1,87 @@
import React, {Component, Fragment} from 'react';
import Divider from '@material-ui/core/Divider';
import EmbarkJS from 'Embark/EmbarkJS';
import IdentityFactory from 'Embark/contracts/IdentityFactory';
import IdentityGasRelay from 'Embark/contracts/IdentityGasRelay';
import PropTypes from 'prop-types';
import Status from './status';
import Tab from '@material-ui/core/Tab';
import Tabs from '@material-ui/core/Tabs';
import {Typography} from '@material-ui/core';
import {withStyles} from '@material-ui/core/styles';
const styles = {};
class Body extends Component {
constructor(props){
super(props);
this.state = {
tab: 0,
identityAddress: null
};
}
componentDidMount(){
EmbarkJS.onReady(err => {
if(err) {
console.error(err);
return;
}
this.setState({
identityAddress: IdentityGasRelay.options.address
});
});
}
handleChange = (event, tab) => {
this.setState({tab});
};
newIdentity = (cb) => {
let toSend = IdentityFactory.methods['createIdentity()']();
toSend.estimateGas()
.then(estimatedGas => {
return toSend.send({gas: estimatedGas + 100000});
})
.then((receipt) => {
const instance = receipt.events.IdentityCreated.returnValues.instance;
this.setState({identityAddress: instance});
cb();
});
}
render(){
const {tab, identityAddress} = this.state;
return <Fragment>
<Tabs value={tab} onChange={this.handleChange}>
<Tab label="Call" />
<Tab label="Approve and Call" />
<Tab label="Deploy" />
</Tabs>
{tab === 0 && <TabContainer>One</TabContainer>}
{tab === 1 && <TabContainer>Item Two</TabContainer>}
{tab === 2 && <TabContainer>Item Three</TabContainer>}
<Divider />
<Status identityCreationFunction={this.newIdentity} identityAddress={identityAddress} />
</Fragment>;
}
}
function TabContainer(props) {
return <Typography component="div" style={{padding: 8 * 3}}>
{props.children}
</Typography>;
}
TabContainer.propTypes = {
children: PropTypes.node.isRequired
};
Body.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(Body);

View File

@ -0,0 +1,41 @@
import React, {Component} from 'react';
import AppBar from '@material-ui/core/AppBar';
import PropTypes from 'prop-types';
import Toolbar from '@material-ui/core/Toolbar';
import {Typography} from '@material-ui/core';
import {withStyles} from '@material-ui/core/styles';
const styles = {
root: {
flexGrow: 1
},
flex: {
flexGrow: 1
},
toolBarTyp: {
color: '#fff'
}
};
class Header extends Component {
render(){
const {classes} = this.props;
return (
<div className={classes.root} >
<AppBar position="static">
<Toolbar className={classes.toolBar}>
<Typography className={classes.toolBarTyp}>Gas Relayer Demo</Typography>
</Toolbar>
</AppBar>
</div>
);
}
}
Header.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(Header);

View File

@ -0,0 +1,212 @@
import React, {Component} from 'react';
import AddIcon from '@material-ui/icons/Add';
import BalanceIcon from '@material-ui/icons/AccountBalance';
import Button from '@material-ui/core/Button';
import CircularProgress from '@material-ui/core/CircularProgress';
import EmbarkJS from 'Embark/EmbarkJS';
import KeyIcon from '@material-ui/icons/VpnKey';
import LinearProgress from '@material-ui/core/LinearProgress';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import PropTypes from 'prop-types';
import RefreshIcon from '@material-ui/icons/Refresh';
import Typography from '@material-ui/core/Typography';
import config from '../config';
import web3 from 'Embark/web3';
import {withStyles} from '@material-ui/core/styles';
const styles = theme => ({
button: {
marginRight: theme.spacing.unit * 10
},
container: {
width: '100%',
position: 'relative'
},
root: {
width: '100%',
maxWidth: 420,
backgroundColor: theme.palette.background.paper
},
right: {
position: 'absolute',
top: theme.spacing.unit * 2,
right: theme.spacing.unit * 2
}
});
class Status extends Component {
constructor(props){
super(props);
this.state = {
'identityEthBalance': 0,
'relayerAddress': null,
'relayerEthBalance': 0,
'block': 0,
'submitState': {
'etherSend': false,
'createIdentity': false
}
};
}
componentDidMount(){
EmbarkJS.onReady(err => {
if(err) {
console.error(err);
return;
}
this.setState({
relayerAddress: config.relayAccount
});
this.updateBalances();
web3.eth.subscribe('newBlockHeaders')
.on("data", (blockHeader) => {
if(blockHeader.number){
this.setState({block: blockHeader.number});
this.updateBalances();
}
});
});
}
updateBalances = () => {
if(this.props.identityAddress){
web3.eth.getBalance(this.props.identityAddress)
.then(identityEthBalance => {
this.setState({identityEthBalance});
});
}
web3.eth.getBalance(this.state.relayerAddress)
.then(relayerEthBalance => {
this.setState({relayerEthBalance});
});
}
createIdentity = (event) => {
event.preventDefault();
let submitState = this.state.submitState;
submitState.createIdentity = true;
this.setState({submitState});
this.props.identityCreationFunction(() => {
submitState = this.state.submitState;
submitState.createIdentity = false;
this.setState({submitState});
});
}
sendEther = (event) => {
event.preventDefault();
let submitState = this.state.submitState;
submitState.etherSend = true;
this.setState({submitState});
web3.eth.sendTransaction({from: web3.eth.defaultAccount, to: this.state.relayerAddress, value: web3.utils.toWei(1, "ether")})
.then((receipt) => {
console.log(receipt);
submitState = this.state.submitState;
submitState.etherSend = false;
this.setState({submitState});
});
}
render(){
const {classes, identityAddress} = this.props;
const {identityEthBalance, relayerAddress, relayerEthBalance, submitState, block} = this.state;
return <div className={classes.container}>
{ (submitState.createIdentity || submitState.etherSend) && <LinearProgress /> }
<List dense={true}>
<ListItem>
<Typography variant="display1">
Identity
</Typography>
<Button className={classes.button} color="primary" aria-label="New Identity" onClick={this.createIdentity} disabled={submitState.createIdentity}>
<RefreshIcon />
Create new identity
</Button>
</ListItem>
<ListItem className={classes.root}>
<ListItemIcon>
<KeyIcon />
</ListItemIcon>
<ListItemText
primary={identityAddress}
secondary="Address"
/>
</ListItem>
<ListItem className={classes.root}>
<ListItemIcon>
<BalanceIcon />
</ListItemIcon>
<ListItemText
primary={identityEthBalance}
secondary="ETH Balance (wei)"
/>
<ListItemText
primary={0}
secondary="STT Balance (wei)"
/>
</ListItem>
</List>
<List dense={true}>
<ListItem>
<Typography variant="display1">
Miner
</Typography>
<Button className={classes.button} color="primary" aria-label="Add ether" onClick={this.sendEther} disabled={submitState.etherSend}>
<AddIcon />
Send ether
</Button>
</ListItem>
<ListItem className={classes.root}>
<ListItemIcon>
<KeyIcon />
</ListItemIcon>
<ListItemText
primary={relayerAddress}
secondary="Address"
/>
</ListItem>
<ListItem className={classes.root}>
<ListItemIcon>
<BalanceIcon />
</ListItemIcon>
<ListItemText
primary={relayerEthBalance}
secondary="ETH Balance (wei)"
/>
<ListItemText
primary={0}
secondary="STT Balance (wei)"
/>
</ListItem>
</List>
<div className={classes.right}>
<CircularProgress />
<Typography>
Block<br />#{block}
</Typography>
</div>
</div>;
}
}
Status.propTypes = {
classes: PropTypes.object.isRequired,
identityAddress: PropTypes.string,
identityCreationFunction: PropTypes.func.isRequired
};
export default withStyles(styles)(Status);

5
test-dapp/app/config.js Normal file
View File

@ -0,0 +1,5 @@
const config = {
"relayAccount": "0x3c72082cbd10a874d673f25e0d48b72d294b5368"
};
export default config;

View File

@ -0,0 +1,4 @@
body {
margin: 0;
background: #eeeeee;
}

View File

@ -1,53 +0,0 @@
div {
margin: 15px;
}
.logs {
background-color: black;
font-size: 14px;
color: white;
font-weight: bold;
padding: 10px;
border-radius: 8px;
}
.tab-content {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
padding: 10px;
margin: 0px;
}
.nav-tabs {
margin-bottom: 0;
}
.status-offline {
vertical-align: middle;
margin-left: 5px;
margin-top: 4px;
width: 12px;
height: 12px;
background: red;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.status-online {
vertical-align: middle;
margin-left: 5px;
margin-top: 4px;
width: 12px;
height: 12px;
background: mediumseagreen;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
input.form-control {
margin: 5px;
}

20
test-dapp/app/dapp.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="css/dapp.css">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="app"></div>
<script type="text/javascript" src="js/dapp.js"></script>
</body>
</html>

16
test-dapp/app/dapp.js Normal file
View File

@ -0,0 +1,16 @@
import React, {Component, Fragment} from 'react';
import Body from './components/body';
import Header from './components/header';
import ReactDOM from 'react-dom';
class App extends Component {
render(){
return <Fragment>
<Header />
<Body />
</Fragment>;
}
}
ReactDOM.render(<App></App>, document.getElementById('app'));

View File

@ -7,7 +7,7 @@ module.exports = {
port: 8545, // Port of the blockchain node
type: "rpc" // Type of connection (ws or rpc),
// Accounts to use instead of the default account to populate your wallet
/*,accounts: [
/*,accounts: [
{
privateKey: "your_private_key",
balance: "5 ether" // You can set the balance of the account in the dev environment
@ -35,6 +35,8 @@ module.exports = {
// TODO: Update to reference 000-gas-relayer branch.
"Identity": {"deploy": false},
"ERC20Receiver": {"deploy": false},
"TestToken": {"deploy": false},
"SafeMath": {"deploy": false},
"DelayedUpdatableInstance": {"deploy": false},
"DelayedUpdatableInstanceStorage": {"deploy": false},
@ -43,9 +45,9 @@ module.exports = {
"InstanceStorage": {"deploy": false},
"MiniMeTokenFactory": {"args":[]},
"MiniMeToken": {"deploy": false},
"RND": {
"STT": {
"instanceOf": "MiniMeToken",
"args":["$MiniMeTokenFactory", "0x0", "0x0", "Random Test Token", 18, "RND", true],
"args":["$MiniMeTokenFactory", "0x0", "0x0", "Status Test Token", 18, "STT", true],
"gasLimit": 4000000
},
"UpdatableInstance": {"deploy": false},

View File

@ -3,6 +3,9 @@
"app": {
"js/relayer-test.js": ["app/relayer-test.js"],
"relayer-test.html": "app/relayer-test.html",
"js/dapp.js": ["app/dapp.js"],
"dapp.html": "app/dapp.html",
"css/dapp.css": ["app/css/**"],
"images/": ["app/images/**"]
},
"buildDir": "dist/",

View File

@ -28,8 +28,12 @@
"eslint-plugin-standard": "^3.1.0"
},
"dependencies": {
"react": "^16.3.2",
"@material-ui/core": "^1.4.3",
"@material-ui/icons": "^2.0.1",
"@material-ui/lab": "^1.0.0-alpha.9",
"react": "^16.4.2",
"react-blockies": "^1.3.0",
"react-bootstrap": "^0.32.1",
"react-dom": "^16.3.2"
"react-dom": "^16.4.2"
}
}