From 590e0ca642452cd665e60ac22c49af24953e0da2 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Sat, 22 Sep 2018 19:21:33 +0200 Subject: [PATCH] eslint fixes --- src/actions/BlockchainActions.js | 100 ++++++-------- src/actions/Web3Actions.js | 219 +++++++++++++++---------------- 2 files changed, 144 insertions(+), 175 deletions(-) diff --git a/src/actions/BlockchainActions.js b/src/actions/BlockchainActions.js index ecec58e0..20e3c77a 100644 --- a/src/actions/BlockchainActions.js +++ b/src/actions/BlockchainActions.js @@ -1,42 +1,28 @@ /* @flow */ -import Web3 from 'web3'; -import HDKey from 'hdkey'; - import EthereumjsUtil from 'ethereumjs-util'; -import EthereumjsUnits from 'ethereumjs-units'; -import EthereumjsTx from 'ethereumjs-tx'; import TrezorConnect from 'trezor-connect'; import BigNumber from 'bignumber.js'; - -import type { EstimateGasOptions } from 'web3'; -import type { TransactionStatus, TransactionReceipt } from 'web3'; -import { strip } from 'utils/ethUtils'; import * as BLOCKCHAIN from 'actions/constants/blockchain'; -import * as WEB3 from 'actions/constants/web3'; import * as PENDING from 'actions/constants/pendingTx'; -import * as AccountsActions from './AccountsActions'; -import * as Web3Actions from './Web3Actions'; - import type { TrezorDevice, Dispatch, GetState, - Action, - AsyncAction, PromiseAction, - ThunkAction, } from 'flowtype'; import type { EthereumAccount } from 'trezor-connect'; import type { Token } from 'reducers/TokensReducer'; import type { NetworkToken } from 'reducers/LocalStorageReducer'; +import * as Web3Actions from './Web3Actions'; +import * as AccountsActions from './AccountsActions'; export type BlockchainAction = { type: typeof BLOCKCHAIN.READY, } -export const discoverAccount = (device: TrezorDevice, address: string, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const discoverAccount = (device: TrezorDevice, address: string, network: string): PromiseAction => async (dispatch: Dispatch): Promise => { // get data from connect // Temporary disabled, enable after trezor-connect@5.0.32 release const txs = await TrezorConnect.ethereumGetAccountInfo({ @@ -44,8 +30,8 @@ export const discoverAccount = (device: TrezorDevice, address: string, network: address, block: 0, transactions: 0, - balance: "0", - nonce: 0 + balance: '0', + nonce: 0, }, coin: network, }); @@ -55,9 +41,9 @@ export const discoverAccount = (device: TrezorDevice, address: string, network: } // blockbook web3 fallback - const web3account = await dispatch( Web3Actions.discoverAccount(address, network) ); + const web3account = await dispatch(Web3Actions.discoverAccount(address, network)); // return { transactions: txs.payload, ...web3account }; - return { + return { address, transactions: txs.payload.transactions, block: txs.payload.block, @@ -66,22 +52,18 @@ export const discoverAccount = (device: TrezorDevice, address: string, network: }; }; -export const getTokenInfo = (input: string, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - return await dispatch( Web3Actions.getTokenInfo(input, network) ); -} +export const getTokenInfo = (input: string, network: string): PromiseAction => async (dispatch: Dispatch): Promise => dispatch(Web3Actions.getTokenInfo(input, network)); -export const getTokenBalance = (token: Token): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - return await dispatch( Web3Actions.getTokenBalance(token) ); -} +export const getTokenBalance = (token: Token): PromiseAction => async (dispatch: Dispatch): Promise => dispatch(Web3Actions.getTokenBalance(token)); -export const getGasPrice = (network: string, defaultGasPrice: number): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const getGasPrice = (network: string, defaultGasPrice: number): PromiseAction => async (dispatch: Dispatch): Promise => { try { - const gasPrice = await dispatch( Web3Actions.getCurrentGasPrice(network) ); + const gasPrice = await dispatch(Web3Actions.getCurrentGasPrice(network)); return new BigNumber(gasPrice); } catch (error) { return new BigNumber(defaultGasPrice); } -} +}; const estimateProxy: Array> = []; export const estimateGasLimit = (network: string, data: string, value: string, gasPrice: string): PromiseAction => async (dispatch: Dispatch): Promise => { @@ -114,9 +96,9 @@ export const onBlockMined = (coinInfo: any): PromiseAction => async (dispa const network: string = coinInfo.shortcut.toLowerCase(); // try to resolve pending transactions - await dispatch( Web3Actions.resolvePendingTransactions(network) ); + await dispatch(Web3Actions.resolvePendingTransactions(network)); - await dispatch( Web3Actions.updateGasPrice(network) ); + await dispatch(Web3Actions.updateGasPrice(network)); const accounts: Array = getState().accounts.filter(a => a.network === network); if (accounts.length > 0) { @@ -125,39 +107,36 @@ export const onBlockMined = (coinInfo: any): PromiseAction => async (dispa accounts, coin: network, }); - + if (response.success) { response.payload.forEach((a, i) => { if (a.transactions > 0) { // load additional data from Web3 (balance, nonce, tokens) - dispatch( Web3Actions.updateAccount(accounts[i], a, network) ) + dispatch(Web3Actions.updateAccount(accounts[i], a, network)); } else { // there are no new txs, just update block - dispatch( AccountsActions.update( { ...accounts[i], block: a.block }) ); + dispatch(AccountsActions.update({ ...accounts[i], block: a.block })); // HACK: since blockbook can't work with smart contracts for now // try to update tokens balances added to this account using Web3 - dispatch( Web3Actions.updateAccountTokens(accounts[i]) ); + dispatch(Web3Actions.updateAccountTokens(accounts[i])); } }); } } -} +}; // not used for now, waiting for fix in blockbook export const onNotification = (payload: any): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - // this event can be triggered multiple times // 1. check if pair [txid + address] is already in reducer const network: string = payload.coin.shortcut.toLowerCase(); const address: string = EthereumjsUtil.toChecksumAddress(payload.tx.address); - const txInfo = await dispatch( Web3Actions.getPendingInfo(network, payload.tx.txid) ); + const txInfo = await dispatch(Web3Actions.getPendingInfo(network, payload.tx.txid)); // const exists = getState().pending.filter(p => p.id === payload.tx.txid && p.address === address); - const exists = getState().pending.filter(p => { - return p.address === address; - }); + const exists = getState().pending.filter(p => p.address === address); if (exists.length < 1) { if (txInfo) { dispatch({ @@ -166,14 +145,14 @@ export const onNotification = (payload: any): PromiseAction => async (disp type: 'send', id: payload.tx.txid, network, - currency: "tETH", + currency: 'tETH', amount: txInfo.value, - total: "0", + total: '0', tx: {}, nonce: txInfo.nonce, address, - rejected: false - } + rejected: false, + }, }); } else { // tx info not found (yet?) @@ -186,18 +165,17 @@ export const onNotification = (payload: any): PromiseAction => async (disp // }); } } -} +}; export const subscribe = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const addresses: Array = getState().accounts.filter(a => a.network === network).map(a => a.address); - // $FlowIssue: trezor-connect@5.0.32 - return await TrezorConnect.blockchainSubscribe({ + const addresses: Array = getState().accounts.filter(a => a.network === network).map(a => a.address); // eslint-disable-line no-unused-vars + await TrezorConnect.blockchainSubscribe({ // accounts: addresses, accounts: [], - coin: network + coin: network, }); -} +}; // Conditionally subscribe to blockchain backend // called after TrezorConnect.init successfully emits TRANSPORT.START event @@ -207,26 +185,26 @@ export const init = (): PromiseAction => async (dispatch: Dispatch, getSta if (getState().discovery.length > 0) { // get unique networks const networks: Array = []; - getState().discovery.forEach(discovery => { + getState().discovery.forEach((discovery) => { if (networks.indexOf(discovery.network) < 0) { networks.push(discovery.network); } }); // subscribe - for (let i = 0; i < networks.length; i++) { - await dispatch( subscribe(networks[i]) ); - } + const results = networks.map(n => dispatch(subscribe(n))); + // wait for all subscriptions + await Promise.all(results); } // continue wallet initialization dispatch({ - type: BLOCKCHAIN.READY + type: BLOCKCHAIN.READY, }); -} +}; // Handle BLOCKCHAIN.ERROR event from TrezorConnect // disconnect and remove Web3 webscocket instance if exists -export const error = (payload: any): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - dispatch( Web3Actions.disconnect(payload.coin) ); -} \ No newline at end of file +export const error = (payload: any): PromiseAction => async (dispatch: Dispatch): Promise => { + dispatch(Web3Actions.disconnect(payload.coin)); +}; \ No newline at end of file diff --git a/src/actions/Web3Actions.js b/src/actions/Web3Actions.js index 5a6ebab7..82249a80 100644 --- a/src/actions/Web3Actions.js +++ b/src/actions/Web3Actions.js @@ -1,15 +1,10 @@ /* @flow */ import Web3 from 'web3'; -import HDKey from 'hdkey'; import BigNumber from 'bignumber.js'; -import EthereumjsUtil from 'ethereumjs-util'; import EthereumjsUnits from 'ethereumjs-units'; -import EthereumjsTx from 'ethereumjs-tx'; // import InputDataDecoder from 'ethereum-input-data-decoder'; -import TrezorConnect from 'trezor-connect'; -import type { EstimateGasOptions, TransactionStatus, TransactionReceipt } from 'web3'; -import { strip } from 'utils/ethUtils'; +import type { EstimateGasOptions } from 'web3'; import * as WEB3 from 'actions/constants/web3'; import * as PENDING from 'actions/constants/pendingTx'; @@ -17,13 +12,11 @@ import type { Dispatch, GetState, ThunkAction, - AsyncAction, PromiseAction, } from 'flowtype'; import type { EthereumAccount } from 'trezor-connect'; import type { Account } from 'reducers/AccountsReducer'; -import type { PendingTx } from 'reducers/PendingTxReducer'; import type { Web3Instance } from 'reducers/Web3Reducer'; import type { Token } from 'reducers/TokensReducer'; import type { NetworkToken } from 'reducers/LocalStorageReducer'; @@ -52,99 +45,95 @@ export type Web3Action = { } | Web3UpdateBlockAction | Web3UpdateGasPriceAction; -export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - return new Promise(async (resolve, reject) => { - // check if requested web was initialized before - const instance = getState().web3.find(w3 => w3.network === network); - if (instance && instance.web3.currentProvider.connected) { - resolve(instance); - return; - } +export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => new Promise(async (resolve, reject) => { + // check if requested web was initialized before + const instance = getState().web3.find(w3 => w3.network === network); + if (instance && instance.web3.currentProvider.connected) { + resolve(instance); + return; + } - // requested web3 wasn't initialized or is disconnected - // initialize again - const { config, ERC20Abi } = getState().localStorage; - const coin = config.coins.find(c => c.network === network); - if (!coin) { - // coin not found - reject(new Error(`Network ${ network} not found in application config.`)); - return; - } + // requested web3 wasn't initialized or is disconnected + // initialize again + const { config, ERC20Abi } = getState().localStorage; + const coin = config.coins.find(c => c.network === network); + if (!coin) { + // coin not found + reject(new Error(`Network ${network} not found in application config.`)); + return; + } - // get first url - const url = coin.web3[ urlIndex ]; - if (!url) { - reject(new Error('Web3 backend is not responding')); - return; - } + // get first url + const url = coin.web3[urlIndex]; + if (!url) { + reject(new Error('Web3 backend is not responding')); + return; + } - const web3 = new Web3( new Web3.providers.WebsocketProvider(url) ); + const web3 = new Web3(new Web3.providers.WebsocketProvider(url)); - const onConnect = async () => { + const onConnect = async () => { + const latestBlock = await web3.eth.getBlockNumber(); + const gasPrice = await web3.eth.getGasPrice(); - const latestBlock = await web3.eth.getBlockNumber(); - const gasPrice = await web3.eth.getGasPrice(); + const newInstance = { + network, + web3, + chainId: coin.chainId, + erc20: new web3.eth.Contract(ERC20Abi), + latestBlock, + gasPrice, + }; - const instance = { - network, - web3, - chainId: coin.chainId, - erc20: new web3.eth.Contract(ERC20Abi), - latestBlock, - gasPrice, - } + dispatch({ + type: WEB3.CREATE, + instance: newInstance, + }); - dispatch({ - type: WEB3.CREATE, - instance, - }); + resolve(newInstance); + }; - resolve(instance); - } + const onEnd = async () => { + web3.currentProvider.reset(); + const oldInstance = getState().web3.find(w3 => w3.network === network); - const onEnd = async () => { - - web3.currentProvider.reset(); - const instance = getState().web3.find(w3 => w3.network === network); - - if (instance && instance.web3.currentProvider.connected) { - // backend disconnects - // dispatch({ - // type: 'WEB3.DISCONNECT', - // network - // }); - } else { - // backend initialization error for given url, try next one - try { - const web3 = await dispatch( initWeb3(network, urlIndex + 1) ); - resolve(web3); - } catch (error) { - reject(error); - } + if (oldInstance && oldInstance.web3.currentProvider.connected) { + // backend disconnects + // dispatch({ + // type: 'WEB3.DISCONNECT', + // network + // }); + } else { + // backend initialization error for given url, try next one + try { + const otherWeb3 = await dispatch(initWeb3(network, urlIndex + 1)); + resolve(otherWeb3); + } catch (error) { + reject(error); } } + }; - web3.currentProvider.on('connect', onConnect); - web3.currentProvider.on('end', onEnd); - web3.currentProvider.on('error', onEnd); - }); -} + web3.currentProvider.on('connect', onConnect); + web3.currentProvider.on('end', onEnd); + web3.currentProvider.on('error', onEnd); +}); -export const discoverAccount = (address: string, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3(network) ); +export const discoverAccount = (address: string, network: string): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance: Web3Instance = await dispatch(initWeb3(network)); const balance = await instance.web3.eth.getBalance(address); const nonce = await instance.web3.eth.getTransactionCount(address); - return { + return { address, transactions: 0, block: 0, balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), - nonce + nonce, }; -} +}; export const resolvePendingTransactions = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3(network) ); + const instance: Web3Instance = await dispatch(initWeb3(network)); const pending = getState().pending.filter(p => p.network === network); for (const tx of pending) { const status = await instance.web3.eth.getTransaction(tx.id); @@ -170,13 +159,14 @@ export const resolvePendingTransactions = (network: string): PromiseAction } } } -} +}; -export const getPendingInfo = (network: string, txid: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3(network) ); +/* +export const getPendingInfo = (network: string, txid: string): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance: Web3Instance = await dispatch(initWeb3(network)); const tx = await instance.web3.eth.getTransaction(txid); - /* + if (tx.input !== "0x") { // find token: // tx.to <= smart contract address @@ -187,34 +177,36 @@ export const getPendingInfo = (network: string, txid: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3("ropsten") ); + // return tx; +}; + +export const getTxInput = (): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance: Web3Instance = await dispatch(initWeb3('ropsten')); // const inputData = instance.web3.utils.hexToAscii("0xa9059cbb00000000000000000000000073d0385f4d8e00c5e6504c6030f47bf6212736a80000000000000000000000000000000000000000000000000000000000000001"); // console.warn("input data!", inputData); -} +}; +*/ - -export const updateAccount = (account: Account, newAccount: EthereumAccount, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3(network) ); +export const updateAccount = (account: Account, newAccount: EthereumAccount, network: string): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance: Web3Instance = await dispatch(initWeb3(network)); const balance = await instance.web3.eth.getBalance(account.address); const nonce = await instance.web3.eth.getTransactionCount(account.address); - dispatch( AccountsActions.update( { ...account, ...newAccount, balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), nonce }) ); + dispatch(AccountsActions.update({ + ...account, ...newAccount, balance: EthereumjsUnits.convert(balance, 'wei', 'ether'), nonce, + })); // update tokens for this account - dispatch( updateAccountTokens(account) ); -} + dispatch(updateAccountTokens(account)); +}; export const updateAccountTokens = (account: Account): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { const tokens = getState().tokens.filter(t => t.network === account.network && t.ethAddress === account.address); for (const token of tokens) { - const balance = await dispatch( getTokenBalance(token) ); + const balance = await dispatch(getTokenBalance(token)); // const newBalance: string = balance.dividedBy(Math.pow(10, token.decimals)).toString(10); if (balance !== token.balance) { dispatch(TokenActions.setBalance( @@ -224,10 +216,10 @@ export const updateAccountTokens = (account: Account): PromiseAction => as )); } } -} +}; -export const getTokenInfo = (address: string, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance: Web3Instance = await dispatch( initWeb3(network) ); +export const getTokenInfo = (address: string, network: string): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance: Web3Instance = await dispatch(initWeb3(network)); const contract = instance.erc20.clone(); contract.options.address = address; @@ -243,40 +235,39 @@ export const getTokenInfo = (address: string, network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const instance = await dispatch( initWeb3(token.network) ); +export const getTokenBalance = (token: Token): PromiseAction => async (dispatch: Dispatch): Promise => { + const instance = await dispatch(initWeb3(token.network)); const contract = instance.erc20.clone(); contract.options.address = token.address; const balance = await contract.methods.balanceOf(token.ethAddress).call(); - return new BigNumber(balance).dividedBy(Math.pow(10, token.decimals)).toString(10); + return new BigNumber(balance).dividedBy(10 ** token.decimals).toString(10); }; export const getCurrentGasPrice = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { const instance = getState().web3.find(w3 => w3.network === network); if (instance) { return EthereumjsUnits.convert(instance.gasPrice, 'wei', 'gwei'); - } else { - throw "0"; } -} + return '0'; +}; -export const updateGasPrice = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { +export const updateGasPrice = (network: string): PromiseAction => async (dispatch: Dispatch): Promise => { try { - const instance = await dispatch( initWeb3(network) ); + const instance = await dispatch(initWeb3(network)); const gasPrice = await instance.web3.eth.getGasPrice(); if (instance.gasPrice !== gasPrice) { dispatch({ type: WEB3.GAS_PRICE_UPDATED, network, - gasPrice + gasPrice, }); } } catch (e) { // silent action // nothing happens if this fails } -} +}; export const estimateGasLimit = (network: string, $options: EstimateGasOptions): PromiseAction => async (dispatch: Dispatch): Promise => { @@ -296,19 +287,19 @@ export const estimateGasLimit = (network: string, $options: EstimateGasOptions): }; export const disconnect = (coinInfo: any): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { - // incoming "coinInfo" from TrezorConnect is CoinInfo | EthereumNetwork type - const network: string = coinInfo.shortcut.toLowerCase(); + // incoming "coinInfo" from TrezorConnect is CoinInfo | EthereumNetwork type + const network: string = coinInfo.shortcut.toLowerCase(); // check if Web3 was already initialized const instance = getState().web3.find(w3 => w3.network === network); if (instance) { // reset current connection instance.web3.currentProvider.reset(); instance.web3.currentProvider.connection.close(); - + // remove instance from reducer dispatch({ type: WEB3.DISCONNECT, - instance + instance, }); } };