mirror of
https://github.com/status-im/snt-gas-relay.git
synced 2025-01-14 16:34:33 +00:00
Adding balance in eth and creation of identities
This commit is contained in:
parent
bd93bb3062
commit
1262299e77
87
test-dapp/app/components/body.js
Normal file
87
test-dapp/app/components/body.js
Normal 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);
|
41
test-dapp/app/components/header.js
Normal file
41
test-dapp/app/components/header.js
Normal 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);
|
212
test-dapp/app/components/status.js
Normal file
212
test-dapp/app/components/status.js
Normal 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
5
test-dapp/app/config.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const config = {
|
||||||
|
"relayAccount": "0x3c72082cbd10a874d673f25e0d48b72d294b5368"
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
4
test-dapp/app/css/dapp.css
Normal file
4
test-dapp/app/css/dapp.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
@ -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
20
test-dapp/app/dapp.html
Normal 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
16
test-dapp/app/dapp.js
Normal 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'));
|
@ -7,7 +7,7 @@ module.exports = {
|
|||||||
port: 8545, // Port of the blockchain node
|
port: 8545, // Port of the blockchain node
|
||||||
type: "rpc" // Type of connection (ws or rpc),
|
type: "rpc" // Type of connection (ws or rpc),
|
||||||
// Accounts to use instead of the default account to populate your wallet
|
// Accounts to use instead of the default account to populate your wallet
|
||||||
/*,accounts: [
|
/*,accounts: [
|
||||||
{
|
{
|
||||||
privateKey: "your_private_key",
|
privateKey: "your_private_key",
|
||||||
balance: "5 ether" // You can set the balance of the account in the dev environment
|
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.
|
// TODO: Update to reference 000-gas-relayer branch.
|
||||||
|
|
||||||
"Identity": {"deploy": false},
|
"Identity": {"deploy": false},
|
||||||
|
"ERC20Receiver": {"deploy": false},
|
||||||
|
"TestToken": {"deploy": false},
|
||||||
"SafeMath": {"deploy": false},
|
"SafeMath": {"deploy": false},
|
||||||
"DelayedUpdatableInstance": {"deploy": false},
|
"DelayedUpdatableInstance": {"deploy": false},
|
||||||
"DelayedUpdatableInstanceStorage": {"deploy": false},
|
"DelayedUpdatableInstanceStorage": {"deploy": false},
|
||||||
@ -43,9 +45,9 @@ module.exports = {
|
|||||||
"InstanceStorage": {"deploy": false},
|
"InstanceStorage": {"deploy": false},
|
||||||
"MiniMeTokenFactory": {"args":[]},
|
"MiniMeTokenFactory": {"args":[]},
|
||||||
"MiniMeToken": {"deploy": false},
|
"MiniMeToken": {"deploy": false},
|
||||||
"RND": {
|
"STT": {
|
||||||
"instanceOf": "MiniMeToken",
|
"instanceOf": "MiniMeToken",
|
||||||
"args":["$MiniMeTokenFactory", "0x0", "0x0", "Random Test Token", 18, "RND", true],
|
"args":["$MiniMeTokenFactory", "0x0", "0x0", "Status Test Token", 18, "STT", true],
|
||||||
"gasLimit": 4000000
|
"gasLimit": 4000000
|
||||||
},
|
},
|
||||||
"UpdatableInstance": {"deploy": false},
|
"UpdatableInstance": {"deploy": false},
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
"app": {
|
"app": {
|
||||||
"js/relayer-test.js": ["app/relayer-test.js"],
|
"js/relayer-test.js": ["app/relayer-test.js"],
|
||||||
"relayer-test.html": "app/relayer-test.html",
|
"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/**"]
|
"images/": ["app/images/**"]
|
||||||
},
|
},
|
||||||
"buildDir": "dist/",
|
"buildDir": "dist/",
|
||||||
|
@ -28,8 +28,12 @@
|
|||||||
"eslint-plugin-standard": "^3.1.0"
|
"eslint-plugin-standard": "^3.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"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-bootstrap": "^0.32.1",
|
||||||
"react-dom": "^16.3.2"
|
"react-dom": "^16.4.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user