Skip to content
This repository has been archived by the owner on Aug 6, 2020. It is now read-only.

Commit

Permalink
Add events poll
Browse files Browse the repository at this point in the history
  • Loading branch information
ylv-io committed Jul 11, 2019
1 parent 3978322 commit b4cc518
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 23 deletions.
76 changes: 55 additions & 21 deletions src/context/Web3Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,73 @@ import Web3 from 'web3';
import { Provider } from 'web3/providers';
import { EventEmitter } from 'events';

import { getNetworkName } from '../util/network';
declare global {
interface Window {
ethereum: Provider;
}
}

export default class Web3Context extends EventEmitter {
export class Web3Context extends EventEmitter {
public connected: boolean;
public accounts: string[] | null;
public networkId: number | null;
public lib: Web3;

public static NetworkIdChangedEventName = 'NetworkIdChanged';
public static AccountsChangedEventName = 'AccountsChanged';
public static ConnectionChangedEventName = 'ConnectionChanged';

private interval: NodeJS.Timeout;

public constructor(provider: Provider | string) {
public constructor(provider: Provider) {
super();

this.lib = new Web3(provider);

this.startPoll();
}

public startPoll(): void {
const poll = async (): Promise<void> => {
try {
// get the current network ID
const newNetworkId = await this.lib.eth.net.getId();
this.updateValueAndFireEvent(newNetworkId, 'networkId', Web3Context.NetworkIdChangedEventName, (): any[] => [
getNetworkName(this.networkId),
]);
// get the accounts
const newAccounts = await this.lib.eth.getAccounts();
this.updateValueAndFireEvent(newAccounts, 'accounts', Web3Context.AccountsChangedEventName);
// if web3 provider calls are success then we are connected
this.updateValueAndFireEvent(true, 'connected', Web3Context.ConnectionChangedEventName);
} catch (e) {
// provider methods fail so we have to update the state and fire the events
this.updateValueAndFireEvent(false, 'connected', Web3Context.ConnectionChangedEventName);
this.updateValueAndFireEvent(null, 'networkId', Web3Context.NetworkIdChangedEventName, (): any[] => [
this.networkId,
getNetworkName(this.networkId),
]);
this.updateValueAndFireEvent(null, 'accounts', Web3Context.AccountsChangedEventName);
// log error here
console.log(e);
}
this.interval = setTimeout(poll, 1000);
};

// start poll to detect web3 provider state change
this.interval = setInterval(this.poll, 100);
this.interval = setTimeout(poll, 1000);
}

private async poll(): Promise<void> {
try {
// get the current network ID
const newNetworkId = await this.lib.eth.net.getId();
// get the accounts
const newAccounts = await this.lib.eth.getAccounts();
} catch (e) {
// provider methods fail so we have to update the state and fire the events
// log error here
private updateValueAndFireEvent<T>(
newValue: T,
property: string,
eventName: string,
getArgs: Function = (): any[] => [],
): void {
if (newValue !== this[property]) {
this[property] = newValue;
this.emit(eventName, this[property], ...getArgs());
}
}

Expand All @@ -55,14 +90,6 @@ export default class Web3Context extends EventEmitter {
} else return Promise.reject(new Error("Web3 provider doesn't support send method"));
}

public async startPoll(): Promise<void> {}

public onAccountsChanged(callback: (accounts: string[] | null) => void) {}

public onNetworkChanged(callback: (networkId: number | null) => void) {}

public onConnectionChanged(callback: (connected: boolean) => void) {}

public getProviderName(): string {
if (!this.lib) return 'unknown';

Expand Down Expand Up @@ -91,7 +118,7 @@ export default class Web3Context extends EventEmitter {
}

export function fromConnection(connection: string): Web3Context {
return new Web3Context(connection);
return new Web3Context(new Web3(connection).currentProvider);
}

export function fromInjected(): Web3Context {
Expand All @@ -101,5 +128,12 @@ export function fromInjected(): Web3Context {
return null;
}

const injected = window.ethereum as any;

// disable auto refresh if possible
if (injected.autoRefreshOnNetworkChange) {
injected.autoRefreshOnNetworkChange = false;
}

return new Web3Context(window.ethereum);
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { fromInjected, fromConnection } from './context/Web3Context';
import { Web3Context, fromInjected, fromConnection } from './context/Web3Context';

export { fromInjected, fromConnection };
export { Web3Context, fromInjected, fromConnection };
54 changes: 54 additions & 0 deletions src/util/network.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export function getNetworkName(networkId): string {
switch (networkId) {
// 0: Olympic, Ethereum public pre-release PoW testnet
case 0:
return 'Olympic';
// 1: Frontier, Homestead, Metropolis, the Ethereum public PoW main network
case 1:
return 'Main';
// 3: Ropsten, the public cross-client Ethereum PoW testnet
case 3:
return 'Ropsten';
// 4: Rinkeby, the public Geth-only PoA testnet
case 4:
return 'Rinkeby';
// 5: Goerli, the public cross-client PoA testnet
case 5:
return 'Goerli';
// 6: Kotti Classic, the public cross-client PoA testnet for Classic
case 6:
return 'Kotti';
// 8: Ubiq, the public Gubiq main network with flux difficulty chain ID 8
case 8:
return 'Ubiq';
// 42: Kovan, the public Parity-only PoA testnet
case 42:
return 'Kovan';
// 60: GoChain, the GoChain networks mainnet
case 60:
return 'GoChain';
// 77: Sokol, the public POA Network testnet
case 77:
return 'Sokol';
// 99: Core, the public POA Network main network
case 99:
return 'Core';
// 100: xDai, the public MakerDAO/POA Network main network
case 100:
return 'xDai';
// 31337: GoChain testnet, the GoChain networks public testnet
case 31337:
return 'GoChain';
// 401697: Tobalaba, the public Energy Web Foundation testnet
case 401697:
return 'Tobalaba';
// 7762959: Musicoin, the music blockchain
case 7762959:
return 'Musicoin';
// 61717561: Aquachain, ASIC resistant chain
case 61717561:
return 'Aquachain';
default:
return 'Private';
}
}

0 comments on commit b4cc518

Please sign in to comment.