mirror of
https://github.com/status-im/snt-gas-relay.git
synced 2025-02-20 01:38:11 +00:00
Adding approveAndCallGasRelayed base component
This commit is contained in:
parent
293c585d87
commit
520859cd27
250
app/components/approveandcallgasrelayed.js
Normal file
250
app/components/approveandcallgasrelayed.js
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
import Web3 from 'web3';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Grid, Row, Form, FormGroup, FormControl, HelpBlock, Button, ControlLabel, Col, InputGroup, Alert } from 'react-bootstrap';
|
||||||
|
|
||||||
|
class ApproveAndCallGasRelayed extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
address: this.props.IdentityGasRelay.options.address,
|
||||||
|
topic: '0x4964656e',
|
||||||
|
to: '0x00',
|
||||||
|
value: 0,
|
||||||
|
data: '0x00',
|
||||||
|
nonce: 0,
|
||||||
|
gasPrice: 0,
|
||||||
|
gasLimit: 0,
|
||||||
|
gasToken: "0x0000000000000000000000000000000000000000",
|
||||||
|
signature: '',
|
||||||
|
symKey: '0xd0d905c1c62b810b787141430417caf2b3f54cffadb395b7bb39fdeb8f17266b',
|
||||||
|
kid: null,
|
||||||
|
skid: null,
|
||||||
|
msgSent: '',
|
||||||
|
payload: '',
|
||||||
|
messages: [],
|
||||||
|
web3W: null,
|
||||||
|
errorMessage: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount(){
|
||||||
|
__embarkContext.execWhenReady(async () => {
|
||||||
|
|
||||||
|
let web3W = new Web3('ws://localhost:8546');
|
||||||
|
|
||||||
|
let _skid = await web3W.shh.addSymKey(this.state.symKey);
|
||||||
|
let _kid = await web3W.shh.newKeyPair();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
kid: _kid,
|
||||||
|
skid: _skid,
|
||||||
|
whisper: web3W
|
||||||
|
});
|
||||||
|
|
||||||
|
web3W.shh.subscribe('messages', {
|
||||||
|
"privateKeyID": _kid,
|
||||||
|
"ttl": 20,
|
||||||
|
"minPow": 0.8,
|
||||||
|
"powTime": 1000
|
||||||
|
}, (error, message, subscription) => {
|
||||||
|
if(error) {
|
||||||
|
console.log(error);
|
||||||
|
this.setState({errorMessage: error.message})
|
||||||
|
} else {
|
||||||
|
this.state.messages.push(this.props.web3.utils.hexToAscii(message.payload));
|
||||||
|
this.setState({messages: this.state.messages})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleChange(e, name){
|
||||||
|
this.state[name] = e.target.value;
|
||||||
|
this.setState(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
async sendMessage(e){
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
messages: [],
|
||||||
|
errorMessage: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
let jsonAbi = this.props.IdentityGasRelay._jsonInterface.filter(x => x.name == "callGasRelayed")[0]
|
||||||
|
let funCall = this.props.web3.eth.abi.encodeFunctionCall(jsonAbi, [this.state.to,
|
||||||
|
this.state.value,
|
||||||
|
this.state.data,
|
||||||
|
this.state.nonce,
|
||||||
|
this.state.gasPrice,
|
||||||
|
this.state.gasLimit,
|
||||||
|
this.state.gasToken,
|
||||||
|
this.state.signature]);
|
||||||
|
let msgObj = {
|
||||||
|
symKeyID: this.state.skid,
|
||||||
|
sig: this.state.kid,
|
||||||
|
ttl: 1000,
|
||||||
|
powTarget: 1,
|
||||||
|
powTime: 20,
|
||||||
|
topic: this.state.topic,
|
||||||
|
payload: this.state.address + funCall.slice(2)
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(msgObj);
|
||||||
|
|
||||||
|
this.props.web3.shh.post(msgObj)
|
||||||
|
.then((err, result) => {
|
||||||
|
console.log(result);
|
||||||
|
console.log(err);
|
||||||
|
this.setState({msgSent: result, payload: msgObj.payload});
|
||||||
|
});
|
||||||
|
} catch(error){
|
||||||
|
console.error(error);
|
||||||
|
this.setState({errorMessage: error.message})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async sign(ev){
|
||||||
|
ev.preventDefault();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
msgSent: false,
|
||||||
|
payload: '',
|
||||||
|
messages: [],
|
||||||
|
errorMessage: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
let message = await this.props.IdentityGasRelay.methods.callGasRelayHash(
|
||||||
|
this.state.to,
|
||||||
|
this.state.value,
|
||||||
|
this.props.web3.utils.soliditySha3({t: 'bytes', v: this.state.data}),
|
||||||
|
this.state.nonce,
|
||||||
|
this.state.gasPrice,
|
||||||
|
this.state.gasLimit,
|
||||||
|
this.state.gasToken
|
||||||
|
).call();
|
||||||
|
|
||||||
|
let accounts = await this.props.web3.eth.getAccounts();
|
||||||
|
let _signature = await this.props.web3.eth.sign(message, accounts[0]);
|
||||||
|
|
||||||
|
this.setState({signature: _signature});
|
||||||
|
} catch(error){
|
||||||
|
console.error(error);
|
||||||
|
this.setState({errorMessage: error.message})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render(){
|
||||||
|
return (<Grid>
|
||||||
|
{
|
||||||
|
this.state.errorMessage != '' ?
|
||||||
|
<React.Fragment>
|
||||||
|
<Alert bsStyle="danger">{this.state.errorMessage}</Alert>
|
||||||
|
</React.Fragment> : ''
|
||||||
|
}
|
||||||
|
<Form>
|
||||||
|
<Row>
|
||||||
|
<Col md={9}>
|
||||||
|
<ControlLabel>Identity Address</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="text" placeholder="Address" defaultValue={this.state.address} onChange={(ev) => this.handleChange(ev, 'address')} />
|
||||||
|
</InputGroup>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={4}>
|
||||||
|
<ControlLabel>To</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="text" defaultValue={this.state.to} onChange={(ev) => this.handleChange(ev, 'to')} />
|
||||||
|
</InputGroup>
|
||||||
|
</Col>
|
||||||
|
<Col md={1}>
|
||||||
|
<ControlLabel>Value</ControlLabel>
|
||||||
|
<FormControl type="string" defaultValue={this.state.value} onChange={(ev) => this.handleChange(ev, 'value')} />
|
||||||
|
</Col>
|
||||||
|
<Col md={4}>
|
||||||
|
<ControlLabel>Data</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="string" defaultValue={this.state.data} onChange={(ev) => this.handleChange(ev, 'data')} />
|
||||||
|
</InputGroup>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={1}>
|
||||||
|
<ControlLabel>Nonce</ControlLabel>
|
||||||
|
<FormControl type="string" defaultValue={this.state.nonce} onChange={(ev) => this.handleChange(ev, 'nonce')} />
|
||||||
|
</Col>
|
||||||
|
<Col md={1}>
|
||||||
|
<ControlLabel>Gas Price</ControlLabel>
|
||||||
|
<FormControl type="string" defaultValue={this.state.gasPrice} onChange={(ev) => this.handleChange(ev, 'gasPrice')} />
|
||||||
|
</Col>
|
||||||
|
<Col md={1}>
|
||||||
|
<ControlLabel>Gas Limit</ControlLabel>
|
||||||
|
<FormControl type="string" defaultValue={this.state.gasLimit} onChange={(ev) => this.handleChange(ev, 'gasLimit')} />
|
||||||
|
</Col>
|
||||||
|
<Col md={6}>
|
||||||
|
<ControlLabel>Gas Token</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="text" defaultValue={this.state.gasToken} onChange={(ev) => this.handleChange(ev, 'gasToken')} />
|
||||||
|
</InputGroup>
|
||||||
|
<HelpBlock>RND: {this.props.RND.options.address}</HelpBlock>
|
||||||
|
<HelpBlock>ETH: 0x0000000000000000000000000000000000000000</HelpBlock>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={4}>
|
||||||
|
<Button bsStyle="primary" onClick={(ev) => this.sign(ev)}>1. Sign Message</Button>
|
||||||
|
</Col>
|
||||||
|
<Col md={5}>
|
||||||
|
<b>Signature: </b>{this.state.signature}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={7}>
|
||||||
|
<ControlLabel>Symmetric Key</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="text" placeholder="Sym Key" defaultValue={this.state.symKey} readOnly={true} />
|
||||||
|
</InputGroup>
|
||||||
|
</Col>
|
||||||
|
<Col md={2}>
|
||||||
|
<ControlLabel>Topic</ControlLabel>
|
||||||
|
<InputGroup>
|
||||||
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
|
<FormControl type="text" readOnly={true} defaultValue={this.state.topic} onChange={(ev) => this.handleChange(ev, 'topic')} />
|
||||||
|
</InputGroup>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Col md={4}>
|
||||||
|
<Button bsStyle="primary" disabled={this.state.signature == ""} onClick={(ev) => this.sendMessage(ev)}>2. Send via whisper</Button>
|
||||||
|
</Col>
|
||||||
|
<Col md={5}>
|
||||||
|
{this.state.msgSent}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<h3>Whisper Messages</h3>
|
||||||
|
{
|
||||||
|
this.state.messages.map((msg, i) => <p key={i}>{msg}</p>)
|
||||||
|
}
|
||||||
|
</Row>
|
||||||
|
</Form>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ApproveAndCallGasRelayed;
|
@ -1,10 +1,7 @@
|
|||||||
import EmbarkJS from 'Embark/EmbarkJS';
|
|
||||||
import IdentityGasRelay from 'Embark/contracts/IdentityGasRelay';
|
|
||||||
import RND from 'Embark/contracts/RND';
|
|
||||||
import Web3 from 'web3';
|
import Web3 from 'web3';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Grid, Row, Form, FormGroup, FormControl, HelpBlock, Button, ControlLabel, Col, InputGroup } from 'react-bootstrap';
|
import { Grid, Row, Form, FormGroup, FormControl, HelpBlock, Button, ControlLabel, Col, InputGroup, Alert } from 'react-bootstrap';
|
||||||
|
|
||||||
class CallGasRelayed extends React.Component {
|
class CallGasRelayed extends React.Component {
|
||||||
|
|
||||||
@ -12,7 +9,7 @@ class CallGasRelayed extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
address: IdentityGasRelay.options.address,
|
address: this.props.IdentityGasRelay.options.address,
|
||||||
topic: '0x4964656e',
|
topic: '0x4964656e',
|
||||||
to: '0x00',
|
to: '0x00',
|
||||||
value: 0,
|
value: 0,
|
||||||
@ -28,12 +25,9 @@ class CallGasRelayed extends React.Component {
|
|||||||
msgSent: '',
|
msgSent: '',
|
||||||
payload: '',
|
payload: '',
|
||||||
messages: [],
|
messages: [],
|
||||||
web3W: null
|
web3W: null,
|
||||||
|
errorMessage: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
window['RND'] = RND;
|
|
||||||
window['IdentityGasRelay'] = IdentityGasRelay;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
@ -56,10 +50,11 @@ class CallGasRelayed extends React.Component {
|
|||||||
"minPow": 0.8,
|
"minPow": 0.8,
|
||||||
"powTime": 1000
|
"powTime": 1000
|
||||||
}, (error, message, subscription) => {
|
}, (error, message, subscription) => {
|
||||||
if(error)
|
if(error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
else {
|
this.setState({errorMessage: error.message})
|
||||||
this.state.messages.push(web3.utils.hexToAscii(message.payload));
|
} else {
|
||||||
|
this.state.messages.push(this.props.web3.utils.hexToAscii(message.payload));
|
||||||
this.setState({messages: this.state.messages})
|
this.setState({messages: this.state.messages})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -75,15 +70,17 @@ class CallGasRelayed extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async sendMessage(e){
|
async sendMessage(e){
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
messages: []
|
messages: [],
|
||||||
|
errorMessage: ''
|
||||||
});
|
});
|
||||||
|
|
||||||
let jsonAbi = IdentityGasRelay._jsonInterface.filter(x => x.name == "callGasRelayed")[0]
|
try {
|
||||||
|
let jsonAbi = this.props.IdentityGasRelay._jsonInterface.filter(x => x.name == "callGasRelayed")[0]
|
||||||
let funCall = web3.eth.abi.encodeFunctionCall(jsonAbi, [this.state.to,
|
let funCall = this.props.web3.eth.abi.encodeFunctionCall(jsonAbi, [this.state.to,
|
||||||
this.state.value,
|
this.state.value,
|
||||||
this.state.data,
|
this.state.data,
|
||||||
this.state.nonce,
|
this.state.nonce,
|
||||||
@ -91,8 +88,6 @@ class CallGasRelayed extends React.Component {
|
|||||||
this.state.gasLimit,
|
this.state.gasLimit,
|
||||||
this.state.gasToken,
|
this.state.gasToken,
|
||||||
this.state.signature]);
|
this.state.signature]);
|
||||||
let message = this.state.address + funCall.slice(2);
|
|
||||||
|
|
||||||
let msgObj = {
|
let msgObj = {
|
||||||
symKeyID: this.state.skid,
|
symKeyID: this.state.skid,
|
||||||
sig: this.state.kid,
|
sig: this.state.kid,
|
||||||
@ -100,52 +95,63 @@ class CallGasRelayed extends React.Component {
|
|||||||
powTarget: 1,
|
powTarget: 1,
|
||||||
powTime: 20,
|
powTime: 20,
|
||||||
topic: this.state.topic,
|
topic: this.state.topic,
|
||||||
payload: message
|
payload: this.state.address + funCall.slice(2)
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(msgObj);
|
console.log(msgObj);
|
||||||
|
|
||||||
web3.shh.post(msgObj)
|
this.props.web3.shh.post(msgObj)
|
||||||
.then((err, result) => {
|
.then((err, result) => {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
console.log(err);
|
console.log(err);
|
||||||
this.setState({msgSent: result, payload: message});
|
this.setState({msgSent: result, payload: msgObj.payload});
|
||||||
});
|
});
|
||||||
|
} catch(error){
|
||||||
|
console.error(error);
|
||||||
|
this.setState({errorMessage: error.message})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async sign(ev){
|
async sign(ev){
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
|
||||||
let dataHash = web3.utils.soliditySha3({t: 'bytes', v: this.state.data} );
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
msgSent: false,
|
msgSent: false,
|
||||||
payload: '',
|
payload: '',
|
||||||
messages: []
|
messages: [],
|
||||||
})
|
errorMessage: ''
|
||||||
|
});
|
||||||
|
|
||||||
let message = await IdentityGasRelay.methods.callGasRelayHash(
|
try {
|
||||||
|
let message = await this.props.IdentityGasRelay.methods.callGasRelayHash(
|
||||||
this.state.to,
|
this.state.to,
|
||||||
this.state.value,
|
this.state.value,
|
||||||
dataHash,
|
this.props.web3.utils.soliditySha3({t: 'bytes', v: this.state.data}),
|
||||||
this.state.nonce,
|
this.state.nonce,
|
||||||
this.state.gasPrice,
|
this.state.gasPrice,
|
||||||
this.state.gasLimit,
|
this.state.gasLimit,
|
||||||
this.state.gasToken
|
this.state.gasToken
|
||||||
).call();
|
).call();
|
||||||
|
|
||||||
console.log("DataHash: " + dataHash);
|
let accounts = await this.props.web3.eth.getAccounts();
|
||||||
console.log("CallGasRelayHash: " + message);
|
let _signature = await this.props.web3.eth.sign(message, accounts[0]);
|
||||||
|
|
||||||
let accounts = await web3.eth.getAccounts();
|
|
||||||
let _signature = await web3.eth.sign(message, accounts[0]);
|
|
||||||
|
|
||||||
this.setState({signature: _signature});
|
this.setState({signature: _signature});
|
||||||
|
} catch(error){
|
||||||
|
console.error(error);
|
||||||
|
this.setState({errorMessage: error.message})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
return (<Grid>
|
return (<Grid>
|
||||||
|
{
|
||||||
|
this.state.errorMessage != '' ?
|
||||||
|
<React.Fragment>
|
||||||
|
<Alert bsStyle="danger">{this.state.errorMessage}</Alert>
|
||||||
|
</React.Fragment> : ''
|
||||||
|
}
|
||||||
<Form>
|
<Form>
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={9}>
|
<Col md={9}>
|
||||||
@ -195,7 +201,7 @@ class CallGasRelayed extends React.Component {
|
|||||||
<InputGroup.Addon>0x</InputGroup.Addon>
|
<InputGroup.Addon>0x</InputGroup.Addon>
|
||||||
<FormControl type="text" defaultValue={this.state.gasToken} onChange={(ev) => this.handleChange(ev, 'gasToken')} />
|
<FormControl type="text" defaultValue={this.state.gasToken} onChange={(ev) => this.handleChange(ev, 'gasToken')} />
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
<HelpBlock>RND: {RND.options.address}</HelpBlock>
|
<HelpBlock>RND: {this.props.RND.options.address}</HelpBlock>
|
||||||
<HelpBlock>ETH: 0x0000000000000000000000000000000000000000</HelpBlock>
|
<HelpBlock>ETH: 0x0000000000000000000000000000000000000000</HelpBlock>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -3,8 +3,11 @@ import ReactDOM from 'react-dom';
|
|||||||
import { Tabs, Tab } from 'react-bootstrap';
|
import { Tabs, Tab } from 'react-bootstrap';
|
||||||
|
|
||||||
import EmbarkJS from 'Embark/EmbarkJS';
|
import EmbarkJS from 'Embark/EmbarkJS';
|
||||||
import CallGasRelayed from './components/callgasrelayed';
|
|
||||||
import RND from 'Embark/contracts/RND';
|
import RND from 'Embark/contracts/RND';
|
||||||
|
import IdentityGasRelay from 'Embark/contracts/IdentityGasRelay';
|
||||||
|
|
||||||
|
import CallGasRelayed from './components/callgasrelayed';
|
||||||
|
import ApproveAndCallGasRelayed from './components/approveandcallgasrelayed';
|
||||||
|
|
||||||
import './relayer-test.css';
|
import './relayer-test.css';
|
||||||
|
|
||||||
@ -12,6 +15,9 @@ class App extends React.Component {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
window['RND'] = RND;
|
||||||
|
window['IdentityGasRelay'] = IdentityGasRelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderStatus(title, available){
|
_renderStatus(title, available){
|
||||||
@ -26,7 +32,10 @@ class App extends React.Component {
|
|||||||
return (<div><h3>IdentityGasRelay - Usage Example</h3>
|
return (<div><h3>IdentityGasRelay - Usage Example</h3>
|
||||||
<Tabs defaultActiveKey={1} id="uncontrolled-tab-example">
|
<Tabs defaultActiveKey={1} id="uncontrolled-tab-example">
|
||||||
<Tab eventKey={1} title="callGasRelayed">
|
<Tab eventKey={1} title="callGasRelayed">
|
||||||
<CallGasRelayed />
|
<CallGasRelayed IdentityGasRelay={IdentityGasRelay} RND={RND} web3={web3} />
|
||||||
|
</Tab>
|
||||||
|
<Tab eventKey={2} title="approveAndCallGasRelayed">
|
||||||
|
<ApproveAndCallGasRelayed IdentityGasRelay={IdentityGasRelay} RND={RND} web3={web3} />
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</div>);
|
</div>);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user