diff options
Diffstat (limited to 'packages/website/ts/web3_wrapper.ts')
-rw-r--r-- | packages/website/ts/web3_wrapper.ts | 163 |
1 files changed, 87 insertions, 76 deletions
diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts index b713f8a33..415df6e8b 100644 --- a/packages/website/ts/web3_wrapper.ts +++ b/packages/website/ts/web3_wrapper.ts @@ -1,34 +1,38 @@ -import {promisify} from '@0xproject/utils'; -import BigNumber from 'bignumber.js'; +import { BigNumber, intervalUtils, promisify } from '@0xproject/utils'; import * as _ from 'lodash'; -import {Dispatcher} from 'ts/redux/dispatcher'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { utils } from 'ts/utils/utils'; import * as Web3 from 'web3'; export class Web3Wrapper { - private dispatcher: Dispatcher; - private web3: Web3; - private prevNetworkId: number; - private shouldPollUserAddress: boolean; - private watchNetworkAndBalanceIntervalId: number; - private prevUserEtherBalanceInEth: BigNumber; - private prevUserAddress: string; - constructor(dispatcher: Dispatcher, provider: Web3.Provider, networkIdIfExists: number, - shouldPollUserAddress: boolean) { - this.dispatcher = dispatcher; - this.prevNetworkId = networkIdIfExists; - this.shouldPollUserAddress = shouldPollUserAddress; + private _dispatcher: Dispatcher; + private _web3: Web3; + private _prevNetworkId: number; + private _shouldPollUserAddress: boolean; + private _watchNetworkAndBalanceIntervalId: NodeJS.Timer; + private _prevUserEtherBalanceInEth: BigNumber; + private _prevUserAddress: string; + constructor( + dispatcher: Dispatcher, + provider: Web3.Provider, + networkIdIfExists: number, + shouldPollUserAddress: boolean, + ) { + this._dispatcher = dispatcher; + this._prevNetworkId = networkIdIfExists; + this._shouldPollUserAddress = shouldPollUserAddress; - this.web3 = new Web3(); - this.web3.setProvider(provider); + this._web3 = new Web3(); + this._web3.setProvider(provider); // tslint:disable-next-line:no-floating-promises - this.startEmittingNetworkConnectionAndUserBalanceStateAsync(); + this._startEmittingNetworkConnectionAndUserBalanceStateAsync(); } public isAddress(address: string) { - return this.web3.isAddress(address); + return this._web3.isAddress(address); } public async getAccountsAsync(): Promise<string[]> { - const addresses = await promisify<string[]>(this.web3.eth.getAccounts)(); + const addresses = await promisify<string[]>(this._web3.eth.getAccounts)(); return addresses; } public async getFirstAccountIfExistsAsync() { @@ -36,112 +40,119 @@ export class Web3Wrapper { if (_.isEmpty(addresses)) { return ''; } - return (addresses)[0]; + return addresses[0]; } public async getNodeVersionAsync(): Promise<string> { - const nodeVersion = await promisify<string>(this.web3.version.getNode)(); + const nodeVersion = await promisify<string>(this._web3.version.getNode)(); return nodeVersion; } public getProviderObj() { - return this.web3.currentProvider; + return this._web3.currentProvider; } public async getNetworkIdIfExists() { try { - const networkId = await this.getNetworkAsync(); + const networkId = await this._getNetworkAsync(); return Number(networkId); } catch (err) { return undefined; } } public async getBalanceInEthAsync(owner: string): Promise<BigNumber> { - const balanceInWei: BigNumber = await promisify<BigNumber>(this.web3.eth.getBalance)(owner); - const balanceEthOldBigNumber = this.web3.fromWei(balanceInWei, 'ether'); + const balanceInWei: BigNumber = await promisify<BigNumber>(this._web3.eth.getBalance)(owner); + const balanceEthOldBigNumber = this._web3.fromWei(balanceInWei, 'ether'); const balanceEth = new BigNumber(balanceEthOldBigNumber); return balanceEth; } public async doesContractExistAtAddressAsync(address: string): Promise<boolean> { - const code = await promisify<string>(this.web3.eth.getCode)(address); + const code = await promisify<string>(this._web3.eth.getCode)(address); // Regex matches 0x0, 0x00, 0x in order to accomodate poorly implemented clients const zeroHexAddressRegex = /^0[xX][0]*$/; const didFindCode = _.isNull(code.match(zeroHexAddressRegex)); return didFindCode; } public async signTransactionAsync(address: string, message: string): Promise<string> { - const signData = await promisify<string>(this.web3.eth.sign)(address, message); + const signData = await promisify<string>(this._web3.eth.sign)(address, message); return signData; } public async getBlockTimestampAsync(blockHash: string): Promise<number> { - const {timestamp} = await promisify<Web3.BlockWithoutTransactionData>(this.web3.eth.getBlock)(blockHash); + const { timestamp } = await promisify<Web3.BlockWithoutTransactionData>(this._web3.eth.getBlock)(blockHash); return timestamp; } public destroy() { - this.stopEmittingNetworkConnectionAndUserBalanceStateAsync(); + this._stopEmittingNetworkConnectionAndUserBalanceStateAsync(); // HACK: stop() is only available on providerEngine instances - const provider = this.web3.currentProvider; + const provider = this._web3.currentProvider; if (!_.isUndefined((provider as any).stop)) { (provider as any).stop(); } } // This should only be called from the LedgerConfigDialog public updatePrevUserAddress(userAddress: string) { - this.prevUserAddress = userAddress; + this._prevUserAddress = userAddress; } - private async getNetworkAsync() { - const networkId = await promisify(this.web3.version.getNetwork)(); + private async _getNetworkAsync() { + const networkId = await promisify(this._web3.version.getNetwork)(); return networkId; } - private async startEmittingNetworkConnectionAndUserBalanceStateAsync() { - if (!_.isUndefined(this.watchNetworkAndBalanceIntervalId)) { + private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() { + if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) { return; // we are already emitting the state } let prevNodeVersion: string; - this.prevUserEtherBalanceInEth = new BigNumber(0); - this.dispatcher.updateNetworkId(this.prevNetworkId); - this.watchNetworkAndBalanceIntervalId = window.setInterval(async () => { - // Check for network state changes - const currentNetworkId = await this.getNetworkIdIfExists(); - if (currentNetworkId !== this.prevNetworkId) { - this.prevNetworkId = currentNetworkId; - this.dispatcher.updateNetworkId(currentNetworkId); - } - - // Check for node version changes - const currentNodeVersion = await this.getNodeVersionAsync(); - if (currentNodeVersion !== prevNodeVersion) { - prevNodeVersion = currentNodeVersion; - this.dispatcher.updateNodeVersion(currentNodeVersion); - } - - if (this.shouldPollUserAddress) { - const userAddressIfExists = await this.getFirstAccountIfExistsAsync(); - // Update makerAddress on network change - if (this.prevUserAddress !== userAddressIfExists) { - this.prevUserAddress = userAddressIfExists; - this.dispatcher.updateUserAddress(userAddressIfExists); + this._prevUserEtherBalanceInEth = new BigNumber(0); + this._dispatcher.updateNetworkId(this._prevNetworkId); + this._watchNetworkAndBalanceIntervalId = intervalUtils.setAsyncExcludingInterval( + async () => { + // Check for network state changes + const currentNetworkId = await this.getNetworkIdIfExists(); + if (currentNetworkId !== this._prevNetworkId) { + this._prevNetworkId = currentNetworkId; + this._dispatcher.updateNetworkId(currentNetworkId); } - // Check for user ether balance changes - if (userAddressIfExists !== '') { - await this.updateUserEtherBalanceAsync(userAddressIfExists); + // Check for node version changes + const currentNodeVersion = await this.getNodeVersionAsync(); + if (currentNodeVersion !== prevNodeVersion) { + prevNodeVersion = currentNodeVersion; + this._dispatcher.updateNodeVersion(currentNodeVersion); } - } else { - // This logic is primarily for the Ledger, since we don't regularly poll for the address - // we simply update the balance for the last fetched address. - if (!_.isEmpty(this.prevUserAddress)) { - await this.updateUserEtherBalanceAsync(this.prevUserAddress); + + if (this._shouldPollUserAddress) { + const userAddressIfExists = await this.getFirstAccountIfExistsAsync(); + // Update makerAddress on network change + if (this._prevUserAddress !== userAddressIfExists) { + this._prevUserAddress = userAddressIfExists; + this._dispatcher.updateUserAddress(userAddressIfExists); + } + + // Check for user ether balance changes + if (userAddressIfExists !== '') { + await this._updateUserEtherBalanceAsync(userAddressIfExists); + } + } else { + // This logic is primarily for the Ledger, since we don't regularly poll for the address + // we simply update the balance for the last fetched address. + if (!_.isEmpty(this._prevUserAddress)) { + await this._updateUserEtherBalanceAsync(this._prevUserAddress); + } } - } - }, 5000); - } - private async updateUserEtherBalanceAsync(userAddress: string) { + }, + 5000, + (err: Error) => { + utils.consoleLog(`Watching network and balances failed: ${err}`); + this._stopEmittingNetworkConnectionAndUserBalanceStateAsync(); + }, + ); + } + private async _updateUserEtherBalanceAsync(userAddress: string) { const balance = await this.getBalanceInEthAsync(userAddress); - if (!balance.eq(this.prevUserEtherBalanceInEth)) { - this.prevUserEtherBalanceInEth = balance; - this.dispatcher.updateUserEtherBalance(balance); + if (!balance.eq(this._prevUserEtherBalanceInEth)) { + this._prevUserEtherBalanceInEth = balance; + this._dispatcher.updateUserEtherBalance(balance); } } - private stopEmittingNetworkConnectionAndUserBalanceStateAsync() { - clearInterval(this.watchNetworkAndBalanceIntervalId); + private _stopEmittingNetworkConnectionAndUserBalanceStateAsync() { + intervalUtils.clearAsyncExcludingInterval(this._watchNetworkAndBalanceIntervalId); } } |