Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
4,570 changes: 2,671 additions & 1,899 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dependencies": {
"bignumber.js": "^6.0.0",
"csvtojson": "^1.1.9",
"ethereum-input-data-decoder": "0.0.3",
"gh-pages": "^1.1.0",
"mobx": "^3.5.1",
"mobx-react": "^4.4.2",
Expand All @@ -25,8 +26,16 @@
"react-validation": "^3.0.7",
"splash-screen": "^4.0.1",
"store2": "^2.7.0",
"swarm-js": "^0.1.37",
"sweetalert": "^2.1.0",
"web3": "^1.0.0-beta.30"
"underscore": "^1.8.3",
"web3": "^1.0.0-beta.33",
"web3-core": "^1.0.0-beta.33",
"web3-core-requestmanager": "^1.0.0-beta.33",
"web3-eth-abi": "^1.0.0-beta.33",
"web3-eth-accounts": "^1.0.0-beta.33",
"web3-eth-contract": "^1.0.0-beta.33",
"web3-eth-personal": "^1.0.0-beta.33"
},
"scripts": {
"build-css": "node-sass-chokidar src/assets/stylesheets/application.scss -o src/assets/stylesheets --output-style=compressed",
Expand Down
Binary file added src/.DS_Store
Binary file not shown.
3 changes: 2 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import { Header, FirstStep, SecondStep, ThirdStep, FourthStep, FifthStep } from './components';
import { Header, FirstStep, SecondStep, ThirdStep, FourthStep, FifthStep, CheckTx } from './components';
import { Route } from 'react-router-dom';
import './assets/stylesheets/application.css';

Expand All @@ -13,6 +13,7 @@ export class App extends React.Component {
<Route exact path="/3" component={ThirdStep}/>
<Route exact path="/4" component={FourthStep}/>
<Route exact path="/5" component={FifthStep}/>
<Route exact path="/checktx" component={CheckTx}/>
</div>
);
}
Expand Down
22 changes: 12 additions & 10 deletions src/components/1.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class FirstStep extends React.Component {
constructor(props){
super(props);
this.tokenStore = props.UiStore.tokenStore;
this.txStore = props.UiStore.txStore;
this.web3Store = props.UiStore.web3Store;
this.onTokenAddress = this.onTokenAddress.bind(this);
this.onDecimalsChange = this.onDecimalsChange.bind(this);
Expand All @@ -67,6 +68,7 @@ export class FirstStep extends React.Component {
this.onParse = this.onParse.bind(this)
}
async onTokenAddress(e){

if(!e){
this.setState({tokenAddress: {label: '', value: ''}})
return
Expand Down Expand Up @@ -122,7 +124,7 @@ export class FirstStep extends React.Component {
enumerable: true,
});
addresses.push(el)
}
}
})
.on('end', () => {
try {
Expand Down Expand Up @@ -158,12 +160,12 @@ export class FirstStep extends React.Component {
}
return (
<div className="container container_bg">

<div className="content">
<div className='sweet-loading'>
<PulseLoader
color={'#123abc'}
loading={this.web3Store.loading}
color={'#123abc'}
loading={this.web3Store.loading}
/>
</div>
<h1 className="title"><strong>Welcome to Token</strong> MultiSender</h1>
Expand All @@ -177,7 +179,7 @@ export class FirstStep extends React.Component {
<div className="form-inline-i form-inline-i_token-address">
<label htmlFor="token-address" className="label">Token Address</label>
<Select.Creatable

isLoading={this.web3Store.loading}
name="form-field-name"
id="token-address"
Expand All @@ -187,7 +189,7 @@ export class FirstStep extends React.Component {
placeholder="Please select a token or input the address"
options={this.web3Store.userTokens.slice()}
/>

</div>
<div className="form-inline-i form-inline-i_token-decimals">
<label htmlFor="token-decimals" className="label">Decimals</label>
Expand All @@ -199,11 +201,11 @@ export class FirstStep extends React.Component {
<Radio value="json" />JSON
<Radio value="csv" />CSV
</RadioGroup>

</label>
<Textarea
<Textarea
disabled={this.web3Store.loading}
data-gram
data-gram
validations={[required]}
placeholder={`Example: ${this.state.placeholder}`}
onBlur={this.onParse} id="addresses-with-balances" className="textarea"></Textarea>
Expand All @@ -213,4 +215,4 @@ export class FirstStep extends React.Component {
</div>
);
}
}
}
156 changes: 156 additions & 0 deletions src/components/checkTx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import React from 'react';
import { Link } from 'react-router-dom';
import Web3Utils from 'web3-utils';
import Form from 'react-validation/build/form';
import Textarea from 'react-validation/build/textarea';
import Button from 'react-validation/build/button';
import { form, control, button } from 'react-validation';
import { inject, observer } from "mobx-react";
import swal from 'sweetalert';
import generateElement from '../generateElement'
import Example from './example.json'

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you need all of those dependencies?

import ExampleCSV from './example.csv'
import { PulseLoader} from 'react-spinners';
import {RadioGroup, Radio} from 'react-radio-group';
import csvtojson from 'csvtojson'
import Select from 'react-select'
import '../assets/stylesheets/react-select.min.css';
import StormMultiSenderABI from '../abis/StormMultisender'

const InputDataDecoder = require('ethereum-input-data-decoder');
const decoder = new InputDataDecoder(StormMultiSenderABI);

const ownInput = ({ error, isChanged, isUsed, ...props }) => (
<div>
{isChanged && isUsed && error}
<input {...props} />
</div>
);
const Input = control(ownInput);

const required = (value) => {
if (!value.toString().trim().length) {
return <span className="error">required</span>;
}
};

const isAddress = (value) => {
if (!Web3Utils.isAddress(value)) {
return <span className="error">Token address is invalid</span>;
}
};
const InvalidJSON = <div>Your JSON is invalid, please visit <a href="https://jsonlint.com/" target="_blank">Online Json Validator</a></div>

const isJson = (value) => {
try {
JSON.parse(value)
} catch(e) {
return InvalidJSON
}
};


@inject("UiStore")
@observer
export class CheckTx extends React.Component {
constructor(props){
super(props);
this.tokenStore = props.UiStore.tokenStore;
this.txStore = props.UiStore.txStore;
this.web3Store = props.UiStore.web3Store;
this.onTxHash = this.onTxHash.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.addresses = []
this.tokenAddress = '';
this.txFailed = true;
}
async onTxHash(e){

const status = await this.txStore.checkTransaction(e.value);
if (status == -1)
{
swal({
content: "Your tx hash is invalid",
icon: "error",
})
return;
}
if (!status.isError)
{
swal({
content: "Transaction is succeded",
icon: "success",
})
return;
}

swal({
content: status.description,
icon: "error",
})

const inputData = decoder.decodeData(status.inputData);
const tokenAddress = `0x${inputData.inputs[0]}`;
const addresses = []
const recAddresses = inputData.inputs[1];
const balances = inputData.inputs[2];
let bindex = 0;

recAddresses.forEach((address)=>{
const addr = {};
addr[`0x${address}`] = Web3Utils.BN(balances[bindex]);
addresses.push(addr);
bindex++;
});
await this.tokenStore.setJsonAddresses(addresses);
await this.tokenStore.setTokenAddress(tokenAddress);
this.txFailed = true;
}
onSubmit(e){
e.preventDefault()

this.tokenStore.setDecimals(0)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? why decimals 0 ?

this.tokenStore.parseAddresses()
this.props.history.push('/3')
}
render () {
const txFailed = this.txFailed;
return (
<div className="container container_bg">

<div className="content">
<div className='sweet-loading'>
<PulseLoader
color={'#123abc'}
loading={this.web3Store.loading}
/>
</div>
<h1 className="title"><strong>Check transaction status</strong></h1>
<p className="description">
Please provide tx hash <br />
</p>
<Form className="form" onSubmit={this.onSubmit}>
<div className="form-inline">
<div className="form-inline-i form-inline-i_token-address">
<label htmlFor="tx-hash" className="label">Tx Hash</label>
<Select.Creatable

isLoading={this.web3Store.loading}
name="form-field-name"
id="tx-hash"
onChange={this.onTxHash}
loadingPlaceholder="Checking your transaction..."
placeholder="Please select or input the tx hash"
options={this.web3Store.userTokens.slice()}
/>

</div>
</div>
<br/>
<Button className="button button_check" disabled>Resend Transaction</Button>
</Form>
</div>
</div>
);
}
}
3 changes: 2 additions & 1 deletion src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export { FirstStep } from './1';
export { SecondStep } from './2';
export { ThirdStep } from './3';
export { FourthStep } from './4';
export { FifthStep } from './5';
export { FifthStep } from './5';
export { CheckTx } from './checkTx';
18 changes: 12 additions & 6 deletions src/stores/tokenStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class TokenStore {
@observable arrayLimit = 0
@observable errors = []
proxyMultiSenderAddress = process.env.REACT_APP_PROXY_MULTISENDER

constructor(rootStore) {
this.web3Store = rootStore.web3Store;
this.gasPriceStore = rootStore.gasPriceStore;
Expand All @@ -35,7 +35,7 @@ class TokenStore {

@action
async getDecimals(address) {
try{
try{
const web3 = this.web3Store.web3;
const token = new web3.eth.Contract(ERC20ABI, address);
this.decimals = await token.methods.decimals().call();
Expand Down Expand Up @@ -106,9 +106,10 @@ class TokenStore {
const web3 = this.web3Store.web3;
const multisender = new web3.eth.Contract(StormMultiSenderABI, this.proxyMultiSenderAddress);
const currentFee = await multisender.methods.currentFee(this.web3Store.defaultAccount).call();

this.currentFee = Web3Utils.fromWei(currentFee)
return this.currentFee
})
})
}
catch(e){
console.error('getCurrentFee',e)
Expand All @@ -122,7 +123,7 @@ class TokenStore {
const multisender = new web3.eth.Contract(StormMultiSenderABI, this.proxyMultiSenderAddress);
this.arrayLimit = await multisender.methods.arrayLimit().call();
return this.arrayLimit
})
})
}
catch(e){
console.error('GetArrayLimit', e)
Expand Down Expand Up @@ -153,6 +154,11 @@ class TokenStore {
this.jsonAddresses = addresses;
}

setParsedAddresses(addresses)
{
this.jsonAddresses = addresses;
}

@action
parseAddresses(){
const newAddresses = []
Expand Down Expand Up @@ -192,10 +198,10 @@ class TokenStore {
const tx = new BN(standardGasPrice).times(new BN('6000000'))
const txFeeMiners = tx.times(new BN(this.totalNumberTx))
const contractFee = new BN(currentFeeInWei).times(this.totalNumberTx);

return Web3Utils.fromWei(txFeeMiners.plus(contractFee).toString(10))
}

}

export default TokenStore;
export default TokenStore;
Loading