aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/ts/blockchain.ts51
-rw-r--r--packages/website/ts/blockchain_watcher.ts19
-rw-r--r--packages/website/ts/components/portal/portal.tsx7
3 files changed, 35 insertions, 42 deletions
diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts
index 16ed8d03a..d55cb6771 100644
--- a/packages/website/ts/blockchain.ts
+++ b/packages/website/ts/blockchain.ts
@@ -121,19 +121,18 @@ export class Blockchain {
injectedWeb3: Web3,
networkIdIfExists: number,
userLedgerProvider: boolean = false,
- ): Promise<Provider> {
+ ): Promise<[Provider, LedgerSubprovider]> {
const doesInjectedWeb3Exist = !_.isUndefined(injectedWeb3);
const isNetworkIdDefined = !_.isUndefined(networkIdIfExists);
const publicNodeUrlsIfExistsForNetworkId = configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkIdIfExists];
const isPublicNodeAvailableForNetworkId = !_.isUndefined(publicNodeUrlsIfExistsForNetworkId);
- let provider;
if (userLedgerProvider && isNetworkIdDefined) {
const isU2FSupported = await utils.isU2FSupportedAsync();
if (!isU2FSupported) {
throw new Error('Cannot update providerType to LEDGER without U2F support');
}
- provider = new ProviderEngine();
+ const provider = new ProviderEngine();
const ledgerWalletConfigs = {
networkId: networkIdIfExists,
ledgerEthereumClientFactoryAsync: ledgerEthereumBrowserClientFactoryAsync,
@@ -148,10 +147,11 @@ export class Blockchain {
});
provider.addProvider(new RedundantSubprovider(rpcSubproviders as Subprovider[]));
provider.start();
+ return [provider, ledgerSubprovider];
} else if (doesInjectedWeb3Exist && isPublicNodeAvailableForNetworkId) {
// We catch all requests involving a users account and send it to the injectedWeb3
// instance. All other requests go to the public hosted node.
- provider = new ProviderEngine();
+ const provider = new ProviderEngine();
provider.addProvider(new InjectedWeb3Subprovider(injectedWeb3.currentProvider));
provider.addProvider(new FilterSubprovider());
const rpcSubproviders = _.map(publicNodeUrlsIfExistsForNetworkId, publicNodeUrl => {
@@ -161,14 +161,15 @@ export class Blockchain {
});
provider.addProvider(new RedundantSubprovider(rpcSubproviders as Subprovider[]));
provider.start();
+ return [provider, undefined];
} else if (doesInjectedWeb3Exist) {
// Since no public node for this network, all requests go to injectedWeb3 instance
- provider = injectedWeb3.currentProvider;
+ return [injectedWeb3.currentProvider, undefined];
} else {
// If no injectedWeb3 instance, all requests fallback to our public hosted mainnet/testnet node
// We do this so that users can still browse the 0x Portal DApp even if they do not have web3
// injected into their browser.
- provider = new ProviderEngine();
+ const provider = new ProviderEngine();
provider.addProvider(new FilterSubprovider());
const networkId = Blockchain._getFallbackNetworkId();
const rpcSubproviders = _.map(configs.PUBLIC_NODE_URLS_BY_NETWORK_ID[networkId], publicNodeUrl => {
@@ -178,9 +179,8 @@ export class Blockchain {
});
provider.addProvider(new RedundantSubprovider(rpcSubproviders as Subprovider[]));
provider.start();
+ return [provider, undefined];
}
-
- return provider;
}
constructor(dispatcher: Dispatcher) {
this._dispatcher = dispatcher;
@@ -243,6 +243,9 @@ export class Blockchain {
public async updateProviderToInjectedAsync(): Promise<void> {
const shouldPollUserAddress = true;
const userLedgerProvider = false;
+ this._dispatcher.updateBlockchainIsLoaded(false);
+ // We don't want to be out of sync with the network metamask declares.
+ const networkId = await Blockchain._getInjectedWeb3ProviderNetworkIdIfExistsAsync();
await this._resetOrInitializeAsync(this.networkId, shouldPollUserAddress, userLedgerProvider);
}
public async setProxyAllowanceAsync(token: Token, amountInBaseUnits: BigNumber): Promise<void> {
@@ -614,8 +617,7 @@ export class Blockchain {
return !_.isUndefined(this._userAddressIfExists);
}
private async _handleInjectedProviderUpdateAsync(update: InjectedProviderUpdate): Promise<void> {
- if (update.networkVersion === 'loading') {
- // Who comes up with this stuff.
+ if (update.networkVersion === 'loading' || !_.isUndefined(this._ledgerSubprovider)) {
return;
}
const updatedNetworkId = _.parseInt(update.networkVersion);
@@ -778,6 +780,7 @@ export class Blockchain {
this._injectedProviderObservable.subscribe(this._handleInjectedProviderUpdateAsync.bind(this));
}
}
+ this._updateProviderName(injectedWeb3);
const shouldPollUserAddress = true;
const shouldUseLedger = false;
await this._resetOrInitializeAsync(this.networkId, shouldPollUserAddress, shouldUseLedger);
@@ -787,15 +790,20 @@ export class Blockchain {
shouldPollUserAddress: boolean = false,
useLedgerProvider: boolean = false,
): Promise<void> {
+ this._dispatcher.updateBlockchainIsLoaded(false);
+ this._dispatcher.updateUserWeiBalance(undefined);
this.networkId = networkId;
- this._dispatcher.updateNetworkId(networkId);
const injectedWeb3 = Blockchain._getInjectedWeb3();
- const provider = await Blockchain._getProviderAsync(injectedWeb3, networkId, useLedgerProvider);
- // if (!_.isUndefined(this._contractWrappers)) {
- // this._contractWrappers.setProvider(provider, networkId);
- // } else {
- // }
- this._contractWrappers = new ContractWrappers(provider, { networkId });
+ const [provider, ledgerSubproviderIfExists] = await Blockchain._getProviderAsync(
+ injectedWeb3,
+ networkId,
+ useLedgerProvider,
+ );
+ if (!_.isUndefined(this._contractWrappers)) {
+ this._contractWrappers.setProvider(provider, networkId);
+ } else {
+ this._contractWrappers = new ContractWrappers(provider, { networkId });
+ }
if (!_.isUndefined(this._blockchainWatcher)) {
this._blockchainWatcher.destroy();
}
@@ -806,9 +814,10 @@ export class Blockchain {
this.networkId,
shouldPollUserAddress,
);
- if (useLedgerProvider) {
+ if (useLedgerProvider && !_.isUndefined(ledgerSubproviderIfExists)) {
// TODO: why?
delete this._userAddressIfExists;
+ this._ledgerSubprovider = ledgerSubproviderIfExists;
this._dispatcher.updateUserAddress(undefined);
this._dispatcher.updateProviderType(ProviderType.Ledger);
} else {
@@ -816,11 +825,13 @@ export class Blockchain {
const userAddresses = await this._web3Wrapper.getAvailableAddressesAsync();
this._userAddressIfExists = userAddresses[0];
this._dispatcher.updateUserAddress(this._userAddressIfExists);
- this._updateProviderName(injectedWeb3);
+ if (!_.isUndefined(injectedWeb3)) {
+ this._dispatcher.updateProviderType(ProviderType.Injected);
+ }
}
- // TOOD: should not call this in ledger case?
await this.fetchTokenInformationAsync();
await this._blockchainWatcher.startEmittingUserBalanceStateAsync();
+ this._dispatcher.updateNetworkId(networkId);
await this._rehydrateStoreWithContractEventsAsync();
}
private _updateProviderName(injectedWeb3: Web3): void {
diff --git a/packages/website/ts/blockchain_watcher.ts b/packages/website/ts/blockchain_watcher.ts
index 5d029d4f1..4112c8a15 100644
--- a/packages/website/ts/blockchain_watcher.ts
+++ b/packages/website/ts/blockchain_watcher.ts
@@ -35,16 +35,6 @@ export class BlockchainWatcher {
public updatePrevUserAddress(userAddress: string): void {
this._prevUserAddressIfExists = userAddress;
}
- // public async startEmittingInjectedProviderNetworkIdAsync(injectedProvider: any): Promise<void> {
- // if (this._isWatchingNetworkId) {
- // return; // we are already watching the network id
- // }
- // const observable = injectedProvider.publicConfigStore;
- // if (observable && observable.subscribe) {
- // observable.subscribe(this._handleInjectedProviderUpdate.bind(this));
- // this._isWatchingNetworkId = true;
- // }
- // }
public async startEmittingUserBalanceStateAsync(): Promise<void> {
if (!_.isUndefined(this._watchBalanceIntervalId)) {
return; // we are already emitting the state
@@ -60,15 +50,6 @@ export class BlockchainWatcher {
},
);
}
- // private _handleInjectedProviderUpdate(update: InjectedProviderUpdate): void {
- // const updatedNetworkId = _.parseInt(update.networkVersion);
- // if (this._prevNetworkId === updatedNetworkId) {
- // return;
- // }
- // this._prevNetworkId = updatedNetworkId;
- // this._dispatcher.updateNetworkId(updatedNetworkId);
- // this._updateBalanceAsync();
- // }
private async _updateBalanceAsync(): Promise<void> {
let prevNodeVersion: string;
// Check for node version changes
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index 58acb435e..bb88e3824 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -182,9 +182,10 @@ export class Portal extends React.Component<PortalProps, PortalState> {
prevPathname: nextProps.location.pathname,
});
}
+
+ // If the address changed, but the network did not, we can just refetch the currently tracked tokens.
if (
- nextProps.userAddress !== this.props.userAddress ||
- nextProps.networkId !== this.props.networkId ||
+ (nextProps.userAddress !== this.props.userAddress && nextProps.networkId === this.props.networkId) ||
nextProps.lastForceTokenStateRefetch !== this.props.lastForceTokenStateRefetch
) {
const trackedTokenAddresses = _.keys(this.state.trackedTokenStateByAddress);
@@ -200,7 +201,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
const newTokenAddresses = _.map(newTokens, token => token.address);
// Add placeholder entry for this token to the state, since fetching the
// balance/allowance is asynchronous
- const trackedTokenStateByAddress = this.state.trackedTokenStateByAddress;
+ const trackedTokenStateByAddress = { ...this.state.trackedTokenStateByAddress };
for (const tokenAddress of newTokenAddresses) {
trackedTokenStateByAddress[tokenAddress] = {
balance: new BigNumber(0),