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 all 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>
);
}
}
}
116 changes: 116 additions & 0 deletions src/components/checkTx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';
import Web3Utils from 'web3-utils';
import Form from 'react-validation/build/form';
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 { PulseLoader} from 'react-spinners';
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);

@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 = false;
}
async onTxHash(e){

let status = {}

try {
status = await this.txStore.checkTransaction(e.value);
} catch (e) {
swal("Error!", e.message, "error")
return;
}

if (!status.isError)
{
swal("Success", "Transaction is succeded", "success")
return;
}

this.txFailed = true;
swal("Error!", status.description, "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;

await this.tokenStore.setTokenAddress(tokenAddress);
const decimal = this.tokenStore.multiplier

recAddresses.forEach((address)=>{
const addr = {};
addr[`0x${address}`] = Web3Utils.BN(balances[bindex]).div(decimal).toString(10)
addresses.push(addr)
bindex++
});
await this.tokenStore.setJsonAddresses(addresses);

this.txFailed = true;
}
onSubmit(e){
e.preventDefault()
if (this.txFailed)
{
this.txStore.setAdditionalGas(5000)
this.tokenStore.parseAddresses()
this.props.history.push('/3')
}
}
render () {

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

name="form-field-name"
id="tx-hash"
onChange={this.onTxHash}
placeholder="Please select or input the tx hash"
/>

</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';
13 changes: 7 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 @@ -192,10 +193,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