From 005a02efeb5ac874e1c1a4dd6679bfa3cc21b1b1 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Sun, 28 Jan 2018 17:45:20 +0100 Subject: Fix bug where could not switch to Ledger and back --- packages/website/ts/blockchain.ts | 43 ++++++++++++---------- .../ts/components/inputs/token_amount_input.tsx | 8 ++-- packages/website/ts/redux/dispatcher.ts | 12 ++++++ packages/website/ts/redux/reducer.ts | 19 ++++++++++ packages/website/ts/types.ts | 1 + packages/website/ts/web3_wrapper.ts | 13 +++---- 6 files changed, 65 insertions(+), 31 deletions(-) (limited to 'packages') diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index 898cb2d01..e0f5a496f 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -37,6 +37,7 @@ import { EtherscanLinkSuffixes, ProviderType, Side, + SideToAssetToken, SignatureData, Token, TokenByAddress, @@ -212,6 +213,7 @@ export class Blockchain { this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress); this._zeroEx.setProvider(provider, this.networkId); await this._postInstantiationOrUpdatingProviderZeroExAsync(); + this._web3Wrapper.startEmittingNetworkConnectionAndUserBalanceStateAsync(); this._dispatcher.updateProviderType(ProviderType.Ledger); } public async updateProviderToInjectedAsync() { @@ -222,17 +224,18 @@ export class Blockchain { } const provider = this._cachedProvider; this.networkId = this._cachedProviderNetworkId; - this._dispatcher.updateNetworkId(this.networkId); this._web3Wrapper.destroy(); const shouldPollUserAddress = true; this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress); this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync(); - this._dispatcher.updateUserAddress(this._userAddress); + this._zeroEx.setProvider(provider, this.networkId); await this._postInstantiationOrUpdatingProviderZeroExAsync(); + await this.fetchTokenInformationAsync(); + this._web3Wrapper.startEmittingNetworkConnectionAndUserBalanceStateAsync(); this._dispatcher.updateProviderType(ProviderType.Injected); delete this._ledgerSubprovider; delete this._cachedProvider; @@ -473,20 +476,10 @@ export class Blockchain { ); this._dispatcher.updateBlockchainIsLoaded(false); - // HACK: Without this timeout, the second call to dispatcher somehow causes blockchainIsLoaded - // to flicker... Need to debug further :(((()))) - await new Promise(resolve => setTimeout(resolve, 100)); this._dispatcher.clearTokenByAddress(); const tokenRegistryTokensByAddress = await this._getTokenRegistryTokensByAddressAsync(); - // HACK: This is a hack so that the loading spinner doesn't show up twice... - // Once for loading the blockchain, another for loading the userAddress - this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync(); - if (!_.isEmpty(this._userAddress)) { - this._dispatcher.updateUserAddress(this._userAddress); - } - let trackedTokensIfExists = trackedTokenStorage.getTrackedTokensIfExists(this._userAddress, this.networkId); const tokenRegistryTokens = _.values(tokenRegistryTokensByAddress); if (_.isUndefined(trackedTokensIfExists)) { @@ -507,14 +500,20 @@ export class Blockchain { }); } const allTokens = _.uniq([...tokenRegistryTokens, ...trackedTokensIfExists]); - this._dispatcher.updateTokenByAddress(allTokens); - const mostPopularTradingPairTokens: Token[] = [ _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[0] }), _.find(allTokens, { symbol: configs.DEFAULT_TRACKED_TOKEN_SYMBOLS[1] }), ]; - this._dispatcher.updateChosenAssetTokenAddress(Side.Deposit, mostPopularTradingPairTokens[0].address); - this._dispatcher.updateChosenAssetTokenAddress(Side.Receive, mostPopularTradingPairTokens[1].address); + const sideToAssetToken: SideToAssetToken = { + [Side.Deposit]: { + address: mostPopularTradingPairTokens[0].address, + }, + [Side.Receive]: { + address: mostPopularTradingPairTokens[1].address, + }, + }; + this._dispatcher.batchDispatch(allTokens, this.networkId, this._userAddress, sideToAssetToken); + this._dispatcher.updateBlockchainIsLoaded(true); } private async _showEtherScanLinkAndAwaitTransactionMinedAsync( @@ -699,17 +698,23 @@ export class Blockchain { } const provider = await Blockchain._getProviderAsync(injectedWeb3, networkIdIfExists); - const networkId = !_.isUndefined(networkIdIfExists) + this.networkId = !_.isUndefined(networkIdIfExists) ? networkIdIfExists : configs.IS_MAINNET_ENABLED ? constants.NETWORK_ID_MAINNET : constants.NETWORK_ID_TESTNET; + this._dispatcher.updateNetworkId(this.networkId); const zeroExConfigs = { - networkId, + networkId: this.networkId, }; this._zeroEx = new ZeroEx(provider, zeroExConfigs); this._updateProviderName(injectedWeb3); const shouldPollUserAddress = true; - this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, networkId, shouldPollUserAddress); + this._web3Wrapper = new Web3Wrapper(this._dispatcher, provider, this.networkId, shouldPollUserAddress); await this._postInstantiationOrUpdatingProviderZeroExAsync(); + this._userAddress = await this._web3Wrapper.getFirstAccountIfExistsAsync(); + this._dispatcher.updateUserAddress(this._userAddress); + await this.fetchTokenInformationAsync(); + this._web3Wrapper.startEmittingNetworkConnectionAndUserBalanceStateAsync(); + await this._rehydrateStoreWithContractEvents(); } // This method should always be run after instantiating or updating the provider // of the ZeroEx instance. diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx index f41d42d02..44f3fc4a8 100644 --- a/packages/website/ts/components/inputs/token_amount_input.tsx +++ b/packages/website/ts/components/inputs/token_amount_input.tsx @@ -41,7 +41,7 @@ export class TokenAmountInput extends React.Component { + const updatedToken = { + ...tokenByAddress[token.address], + ...token, + }; + tokenByAddress[token.address] = updatedToken; + }); + return { + ...state, + networkId: action.data.networkId, + userAddress: action.data.userAddress, + sideToAssetToken: action.data.sideToAssetToken, + tokenByAddress, + }; + } + case ActionTypes.ForceTokenStateRefetch: return { ...state, diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 134d4d7bf..aeba3a570 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -110,6 +110,7 @@ export enum BalanceErrs { export enum ActionTypes { // Portal + BatchDispatch = 'BATCH_DISPATCH', UpdateScreenWidth = 'UPDATE_SCREEN_WIDTH', UpdateNodeVersion = 'UPDATE_NODE_VERSION', ResetState = 'RESET_STATE', diff --git a/packages/website/ts/web3_wrapper.ts b/packages/website/ts/web3_wrapper.ts index 415df6e8b..e19b0ea06 100644 --- a/packages/website/ts/web3_wrapper.ts +++ b/packages/website/ts/web3_wrapper.ts @@ -24,9 +24,6 @@ export class Web3Wrapper { this._web3 = new Web3(); this._web3.setProvider(provider); - - // tslint:disable-next-line:no-floating-promises - this._startEmittingNetworkConnectionAndUserBalanceStateAsync(); } public isAddress(address: string) { return this._web3.isAddress(address); @@ -90,11 +87,7 @@ export class Web3Wrapper { public updatePrevUserAddress(userAddress: string) { this._prevUserAddress = userAddress; } - private async _getNetworkAsync() { - const networkId = await promisify(this._web3.version.getNetwork)(); - return networkId; - } - private async _startEmittingNetworkConnectionAndUserBalanceStateAsync() { + public async startEmittingNetworkConnectionAndUserBalanceStateAsync() { if (!_.isUndefined(this._watchNetworkAndBalanceIntervalId)) { return; // we are already emitting the state } @@ -145,6 +138,10 @@ export class Web3Wrapper { }, ); } + private async _getNetworkAsync() { + const networkId = await promisify(this._web3.version.getNetwork)(); + return networkId; + } private async _updateUserEtherBalanceAsync(userAddress: string) { const balance = await this.getBalanceInEthAsync(userAddress); if (!balance.eq(this._prevUserEtherBalanceInEth)) { -- cgit