diff --git a/app/components/approveandcallgasrelayed.js b/app/components/approveandcallgasrelayed.js new file mode 100644 index 0000000..6d51416 --- /dev/null +++ b/app/components/approveandcallgasrelayed.js @@ -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 ( + { + this.state.errorMessage != '' ? + + {this.state.errorMessage} + : '' + } +
+ + + Identity Address + + 0x + this.handleChange(ev, 'address')} /> + + + + + + To + + 0x + this.handleChange(ev, 'to')} /> + + + + Value + this.handleChange(ev, 'value')} /> + + + Data + + 0x + this.handleChange(ev, 'data')} /> + + + + + + Nonce + this.handleChange(ev, 'nonce')} /> + + + Gas Price + this.handleChange(ev, 'gasPrice')} /> + + + Gas Limit + this.handleChange(ev, 'gasLimit')} /> + + + Gas Token + + 0x + this.handleChange(ev, 'gasToken')} /> + + RND: {this.props.RND.options.address} + ETH: 0x0000000000000000000000000000000000000000 + + + + + + + + Signature: {this.state.signature} + + + + + Symmetric Key + + 0x + + + + + Topic + + 0x + this.handleChange(ev, 'topic')} /> + + + + + + + + + {this.state.msgSent} + + + + +

Whisper Messages

+ { + this.state.messages.map((msg, i) =>

{msg}

) + } +
+
+
+ ); + } + } + + export default ApproveAndCallGasRelayed; \ No newline at end of file diff --git a/app/components/callgasrelayed.js b/app/components/callgasrelayed.js index 5884567..1c491d1 100644 --- a/app/components/callgasrelayed.js +++ b/app/components/callgasrelayed.js @@ -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 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 { @@ -12,7 +9,7 @@ class CallGasRelayed extends React.Component { super(props); this.state = { - address: IdentityGasRelay.options.address, + address: this.props.IdentityGasRelay.options.address, topic: '0x4964656e', to: '0x00', value: 0, @@ -28,12 +25,9 @@ class CallGasRelayed extends React.Component { msgSent: '', payload: '', messages: [], - web3W: null + web3W: null, + errorMessage: '' }; - - window['RND'] = RND; - window['IdentityGasRelay'] = IdentityGasRelay; - } componentDidMount(){ @@ -56,10 +50,11 @@ class CallGasRelayed extends React.Component { "minPow": 0.8, "powTime": 1000 }, (error, message, subscription) => { - if(error) + if(error) { console.log(error); - else { - this.state.messages.push(web3.utils.hexToAscii(message.payload)); + this.setState({errorMessage: error.message}) + } else { + this.state.messages.push(this.props.web3.utils.hexToAscii(message.payload)); this.setState({messages: this.state.messages}) } }); @@ -75,77 +70,88 @@ class CallGasRelayed extends React.Component { } async sendMessage(e){ + e.preventDefault(); 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 = 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) + }; - let funCall = 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 message = this.state.address + funCall.slice(2); + console.log(msgObj); - let msgObj = { - symKeyID: this.state.skid, - sig: this.state.kid, - ttl: 1000, - powTarget: 1, - powTime: 20, - topic: this.state.topic, - payload: message - }; - - console.log(msgObj); - - web3.shh.post(msgObj) - .then((err, result) => { - console.log(result); - console.log(err); - this.setState({msgSent: result, payload: message}); - }); + 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(); - let dataHash = web3.utils.soliditySha3({t: 'bytes', v: this.state.data} ); - this.setState({ msgSent: false, payload: '', - messages: [] - }) + messages: [], + errorMessage: '' + }); - let message = await IdentityGasRelay.methods.callGasRelayHash( - this.state.to, - this.state.value, - dataHash, - this.state.nonce, - this.state.gasPrice, - this.state.gasLimit, - this.state.gasToken - ).call(); + 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(); - console.log("DataHash: " + dataHash); - console.log("CallGasRelayHash: " + message); + let accounts = await this.props.web3.eth.getAccounts(); + 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(){ return ( + { + this.state.errorMessage != '' ? + + {this.state.errorMessage} + : '' + }
@@ -195,7 +201,7 @@ class CallGasRelayed extends React.Component { 0x this.handleChange(ev, 'gasToken')} /> - RND: {RND.options.address} + RND: {this.props.RND.options.address} ETH: 0x0000000000000000000000000000000000000000 diff --git a/app/relayer-test.js b/app/relayer-test.js index 1cc439b..271a96a 100644 --- a/app/relayer-test.js +++ b/app/relayer-test.js @@ -3,8 +3,11 @@ import ReactDOM from 'react-dom'; import { Tabs, Tab } from 'react-bootstrap'; import EmbarkJS from 'Embark/EmbarkJS'; -import CallGasRelayed from './components/callgasrelayed'; 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'; @@ -12,6 +15,9 @@ class App extends React.Component { constructor(props) { super(props); + + window['RND'] = RND; + window['IdentityGasRelay'] = IdentityGasRelay; } _renderStatus(title, available){ @@ -26,7 +32,10 @@ class App extends React.Component { return (

IdentityGasRelay - Usage Example

- + + + +
);