2018-10-03 09:36:13 -04:00
|
|
|
import React, { Fragment } from 'react';
|
|
|
|
import ReactDOM from 'react-dom';
|
2018-10-03 08:45:56 -04:00
|
|
|
import EmbarkJS from 'Embark/EmbarkJS';
|
2018-10-03 09:36:13 -04:00
|
|
|
import web3 from 'Embark/web3'
|
2018-10-03 10:13:40 -04:00
|
|
|
import merkleData from './merkle';
|
2018-10-04 10:09:29 -04:00
|
|
|
import { sha3 } from 'ethereumjs-util';
|
|
|
|
import merkle from 'merkle-tree-solidity';
|
2018-10-03 12:03:22 -04:00
|
|
|
import SNTGiveaway from 'Embark/contracts/SNTGiveaway';
|
2018-10-03 14:28:33 -04:00
|
|
|
import SNT from 'Embark/contracts/SNT';
|
2018-10-04 21:55:45 -04:00
|
|
|
import axios from 'axios';
|
2018-10-03 14:28:33 -04:00
|
|
|
|
2018-10-03 12:03:22 -04:00
|
|
|
window.SNTGiveaway = SNTGiveaway;
|
2018-10-03 14:28:33 -04:00
|
|
|
window.SNT = SNT;
|
2018-10-03 12:03:22 -04:00
|
|
|
|
2018-10-03 09:36:13 -04:00
|
|
|
class App extends React.Component {
|
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2018-10-04 10:09:29 -04:00
|
|
|
this.state = {
|
|
|
|
error: false,
|
2018-10-04 11:21:43 -04:00
|
|
|
errorMessage: '',
|
2018-10-04 21:55:45 -04:00
|
|
|
ready: false,
|
|
|
|
showENSLink: false
|
2018-10-04 10:09:29 -04:00
|
|
|
};
|
2018-10-03 09:36:13 -04:00
|
|
|
}
|
2018-10-03 10:13:40 -04:00
|
|
|
|
|
|
|
componentDidMount(){
|
|
|
|
EmbarkJS.onReady(async (error) => {
|
2018-10-04 11:21:43 -04:00
|
|
|
|
2018-10-03 10:13:40 -04:00
|
|
|
if(error){
|
2018-10-04 11:21:43 -04:00
|
|
|
this.setState({error: true, errorMessage: "Error loading the DAPP - Contact your nearest Status Core Developer"});
|
|
|
|
console.error(error);
|
2018-10-03 10:13:40 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
try {
|
|
|
|
await this.start();
|
|
|
|
} catch (error) {
|
2018-10-04 11:21:43 -04:00
|
|
|
this.setState({error: true, errorMessage: "Error loading the DAPP - Contact your nearest Status Core Developer"});
|
2018-10-04 21:55:45 -04:00
|
|
|
console.error(error);
|
|
|
|
return;
|
|
|
|
}
|
2018-10-03 10:13:40 -04:00
|
|
|
});
|
2018-10-04 11:21:43 -04:00
|
|
|
}
|
|
|
|
|
2018-10-04 13:31:50 -04:00
|
|
|
async redirectIfProcessed(code){
|
|
|
|
const sentToAddress = await SNTGiveaway.methods.sentToAddress(web3.eth.defaultAccount).call();
|
|
|
|
const usedCode = await SNTGiveaway.methods.codeUsed( '0x' + code,).call();
|
2018-10-04 21:55:45 -04:00
|
|
|
|
2018-10-04 13:31:50 -04:00
|
|
|
if(sentToAddress || usedCode){
|
2018-10-04 21:55:45 -04:00
|
|
|
this.setState({showENSLink: true});
|
2018-10-04 13:31:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
async start(){
|
|
|
|
const code = location.search.replace("?", ''); // QR code value, i.e.: a8cd4b33bc
|
2018-10-04 11:21:43 -04:00
|
|
|
const accounts = await web3.eth.getAccounts();
|
|
|
|
|
|
|
|
web3.eth.defaultAccount = accounts[0];
|
|
|
|
|
|
|
|
if(!code) {
|
|
|
|
this.setState({error: true, errorMessage: "Code is required"});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const merkleTree = new merkle(merkleData.elements);
|
2018-10-04 13:31:50 -04:00
|
|
|
const hashedCode = sha3('0x' + code);
|
2018-10-04 11:21:43 -04:00
|
|
|
|
2018-10-04 13:31:50 -04:00
|
|
|
let proof;
|
|
|
|
try {
|
|
|
|
proof = merkleTree.getProof(hashedCode);
|
|
|
|
} catch(error){
|
|
|
|
this.setState({error: true, errorMessage: "Invalid Code"});
|
|
|
|
console.log(error);
|
|
|
|
return;
|
2018-10-04 11:21:43 -04:00
|
|
|
}
|
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
await this.redirectIfProcessed(code);
|
2018-10-04 11:21:43 -04:00
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
if(!this.state.showENSLink){
|
|
|
|
const validRequest = await SNTGiveaway.methods.validRequest(proof, '0x' + code, web3.eth.defaultAccount).call();
|
|
|
|
if(!validRequest){
|
|
|
|
this.setState({error: true, errorMessage: "Invalid Code"});
|
|
|
|
console.error("Request is not valid according to contract");
|
|
|
|
return;
|
2018-10-04 13:31:50 -04:00
|
|
|
}
|
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
// Create / Open a database
|
|
|
|
const response = await axios.get('http://localhost:3000/isProcessing/' + code); // TODO: extract to config
|
|
|
|
if(!response.data.result){
|
|
|
|
const record = {
|
|
|
|
code,
|
|
|
|
address: web3.eth.defaultAccount,
|
|
|
|
proof: proof.map(x => '0x' + x.toString('hex'))
|
|
|
|
}
|
2018-10-04 13:31:50 -04:00
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
const response = await axios.post('http://localhost:3000/requestFunds/', record);
|
2018-10-04 13:31:50 -04:00
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
console.log(response);
|
2018-10-04 11:21:43 -04:00
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
// TODO: avoid people spamming with localstorage
|
|
|
|
} else {
|
|
|
|
console.log("Transaction already exists");
|
|
|
|
}
|
|
|
|
|
|
|
|
setInterval(async () => {
|
|
|
|
await this.redirectIfProcessed(code);
|
|
|
|
}, 10000);
|
|
|
|
}
|
2018-10-04 13:31:50 -04:00
|
|
|
|
|
|
|
|
2018-10-04 11:21:43 -04:00
|
|
|
this.setState({ready: true});
|
2018-10-03 10:13:40 -04:00
|
|
|
}
|
2018-10-03 09:36:13 -04:00
|
|
|
|
|
|
|
render(){
|
2018-10-04 21:55:45 -04:00
|
|
|
const {error, errorMessage, ready, showENSLink} = this.state;
|
2018-10-04 13:31:50 -04:00
|
|
|
|
|
|
|
return <Fragment>
|
|
|
|
{ error && <h2>{errorMessage}</h2> }
|
|
|
|
|
|
|
|
{ !ready && !error && <h2>Add a loading message / indicator that the dapp is checking whether the code is valid or not </h2> }
|
|
|
|
|
2018-10-04 21:55:45 -04:00
|
|
|
{ ready && !showENSLink && <h2>Add a message indicating that the code has been received, and we're processing the trx</h2> }
|
|
|
|
|
|
|
|
{ showENSLink && !error && <h2>Show link or redirect to ENS DAPP</h2> }
|
2018-10-04 13:31:50 -04:00
|
|
|
</Fragment>
|
2018-10-03 09:36:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 08:45:56 -04:00
|
|
|
|
2018-10-03 09:36:13 -04:00
|
|
|
ReactDOM.render(<App></App>, document.getElementById('app'));
|