Add New Networks (#1259)

* Add new networks.

* Handle typing issues with DPath being possibly undefined.

* Remove copied nodes from tests.

* Review comments, refactor makeExplorer.

* Remove ETSC

* Re-add import

* Update snapshot
This commit is contained in:
William O'Beirne 2018-04-06 10:02:02 -04:00 committed by Daniel Ternyak
parent ab2b559dd2
commit 8fb0e03d8d
13 changed files with 245 additions and 129 deletions

View File

@ -1,21 +1,22 @@
import './LedgerNano.scss';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import translate from 'translations';
import DeterministicWalletsModal from './DeterministicWalletsModal';
import { LedgerWallet } from 'libs/wallet';
import ledger from 'ledgerco'; import ledger from 'ledgerco';
import translate, { translateRaw } from 'translations';
import DeterministicWalletsModal from './DeterministicWalletsModal';
import UnsupportedNetwork from './UnsupportedNetwork';
import { LedgerWallet } from 'libs/wallet';
import { Spinner, NewTabLink } from 'components/ui'; import { Spinner, NewTabLink } from 'components/ui';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { AppState } from 'reducers'; import { AppState } from 'reducers';
import { SecureWalletName, ledgerReferralURL } from 'config'; import { SecureWalletName, ledgerReferralURL } from 'config';
import { getPaths, getSingleDPath } from 'selectors/config/wallet'; import { getPaths, getSingleDPath } from 'selectors/config/wallet';
import './LedgerNano.scss';
interface OwnProps { interface OwnProps {
onUnlock(param: any): void; onUnlock(param: any): void;
} }
interface StateProps { interface StateProps {
dPath: DPath; dPath: DPath | undefined;
dPaths: DPath[]; dPaths: DPath[];
} }
@ -34,7 +35,7 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
public state: State = { public state: State = {
publicKey: '', publicKey: '',
chainCode: '', chainCode: '',
dPath: this.props.dPath.value, dPath: this.props.dPath ? this.props.dPath.value : '',
error: null, error: null,
isLoading: false, isLoading: false,
showTip: false showTip: false
@ -48,7 +49,7 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
public componentWillReceiveProps(nextProps: Props) { public componentWillReceiveProps(nextProps: Props) {
if (this.props.dPath !== nextProps.dPath) { if (this.props.dPath !== nextProps.dPath) {
this.setState({ dPath: nextProps.dPath.value }); this.setState({ dPath: nextProps.dPath ? nextProps.dPath.value : '' });
} }
} }
@ -56,6 +57,10 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
const { dPath, publicKey, chainCode, error, isLoading, showTip } = this.state; const { dPath, publicKey, chainCode, error, isLoading, showTip } = this.state;
const showErr = error ? 'is-showing' : ''; const showErr = error ? 'is-showing' : '';
if (!dPath) {
return <UnsupportedNetwork walletType={translateRaw('x_Ledger')} />;
}
if (window.location.protocol !== 'https:') { if (window.location.protocol !== 'https:') {
return ( return (
<div className="LedgerDecrypt"> <div className="LedgerDecrypt">
@ -167,7 +172,7 @@ class LedgerNanoSDecryptClass extends PureComponent<Props, State> {
this.setState({ this.setState({
publicKey: '', publicKey: '',
chainCode: '', chainCode: '',
dPath: this.props.dPath.value dPath: this.props.dPath ? this.props.dPath.value : ''
}); });
} }
} }

View File

@ -155,7 +155,8 @@ class MnemonicDecryptClass extends PureComponent<Props, State> {
function mapStateToProps(state: AppState): StateProps { function mapStateToProps(state: AppState): StateProps {
return { return {
dPath: getSingleDPath(state, InsecureWalletName.MNEMONIC_PHRASE), // Mnemonic dPath is guaranteed to always be provided
dPath: getSingleDPath(state, InsecureWalletName.MNEMONIC_PHRASE) as DPath,
dPaths: getPaths(state, InsecureWalletName.MNEMONIC_PHRASE) dPaths: getPaths(state, InsecureWalletName.MNEMONIC_PHRASE)
}; };
} }

View File

@ -1,14 +1,15 @@
import { TrezorWallet, TREZOR_MINIMUM_FIRMWARE } from 'libs/wallet'; import { TrezorWallet, TREZOR_MINIMUM_FIRMWARE } from 'libs/wallet';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import translate from 'translations'; import translate, { translateRaw } from 'translations';
import TrezorConnect from 'vendor/trezor-connect'; import TrezorConnect from 'vendor/trezor-connect';
import DeterministicWalletsModal from './DeterministicWalletsModal'; import DeterministicWalletsModal from './DeterministicWalletsModal';
import './Trezor.scss'; import UnsupportedNetwork from './UnsupportedNetwork';
import { Spinner, NewTabLink } from 'components/ui'; import { Spinner, NewTabLink } from 'components/ui';
import { AppState } from 'reducers'; import { AppState } from 'reducers';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { SecureWalletName, trezorReferralURL } from 'config'; import { SecureWalletName, trezorReferralURL } from 'config';
import { getSingleDPath, getPaths } from 'selectors/config/wallet'; import { getSingleDPath, getPaths } from 'selectors/config/wallet';
import './Trezor.scss';
//todo: conflicts with comment in walletDecrypt -> onUnlock method //todo: conflicts with comment in walletDecrypt -> onUnlock method
interface OwnProps { interface OwnProps {
@ -16,7 +17,7 @@ interface OwnProps {
} }
interface StateProps { interface StateProps {
dPath: DPath; dPath: DPath | undefined;
dPaths: DPath[]; dPaths: DPath[];
} }
@ -35,14 +36,14 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
public state: State = { public state: State = {
publicKey: '', publicKey: '',
chainCode: '', chainCode: '',
dPath: this.props.dPath.value, dPath: this.props.dPath ? this.props.dPath.value : '',
error: null, error: null,
isLoading: false isLoading: false
}; };
public componentWillReceiveProps(nextProps: Props) { public componentWillReceiveProps(nextProps: Props) {
if (this.props.dPath !== nextProps.dPath) { if (this.props.dPath !== nextProps.dPath) {
this.setState({ dPath: nextProps.dPath.value }); this.setState({ dPath: nextProps.dPath ? nextProps.dPath.value : '' });
} }
} }
@ -50,6 +51,10 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
const { dPath, publicKey, chainCode, error, isLoading } = this.state; const { dPath, publicKey, chainCode, error, isLoading } = this.state;
const showErr = error ? 'is-showing' : ''; const showErr = error ? 'is-showing' : '';
if (!dPath) {
return <UnsupportedNetwork walletType={translateRaw('x_Trezor')} />;
}
return ( return (
<div className="TrezorDecrypt"> <div className="TrezorDecrypt">
<button <button
@ -141,7 +146,7 @@ class TrezorDecryptClass extends PureComponent<Props, State> {
this.setState({ this.setState({
publicKey: '', publicKey: '',
chainCode: '', chainCode: '',
dPath: this.props.dPath.value dPath: this.props.dPath ? this.props.dPath.value : ''
}); });
} }
} }

View File

@ -0,0 +1,27 @@
import React from 'react';
import { connect } from 'react-redux';
import { getNetworkConfig } from 'selectors/config';
import { NetworkConfig } from 'types/network';
import { AppState } from 'reducers';
interface StateProps {
network: NetworkConfig;
}
interface OwnProps {
walletType: string | React.ReactElement<string>;
}
type Props = OwnProps & StateProps;
const UnsupportedNetwork: React.SFC<Props> = ({ walletType, network }) => {
return (
<h2>
{walletType} does not support the {network.name} network
</h2>
);
};
export default connect((state: AppState): StateProps => ({
network: getNetworkConfig(state)
}))(UnsupportedNetwork);

View File

@ -38,6 +38,21 @@ export const UBQ_DEFAULT: DPath = {
value: "m/44'/108'/0'/0" value: "m/44'/108'/0'/0"
}; };
export const POA_DEFAULT: DPath = {
label: 'Default (POA)',
value: "m/44'/60'/0'/0"
};
export const TOMO_DEFAULT: DPath = {
label: 'Default (TOMO)',
value: "m/44'/1'/0'/0"
};
export const ELLA_DEFAULT: DPath = {
label: 'Default (ELLA)',
value: "m/44'/163'/0'/0"
};
export const ETH_SINGULAR: DPath = { export const ETH_SINGULAR: DPath = {
label: 'SingularDTV', label: 'SingularDTV',
value: "m/0'/0'/0'" value: "m/0'/0'/0'"
@ -51,7 +66,10 @@ export const DPaths: DPath[] = [
ETC_TREZOR, ETC_TREZOR,
ETH_TESTNET, ETH_TESTNET,
EXP_DEFAULT, EXP_DEFAULT,
UBQ_DEFAULT UBQ_DEFAULT,
POA_DEFAULT,
TOMO_DEFAULT,
ELLA_DEFAULT
]; ];
// PATHS TO BE INCLUDED REGARDLESS OF WALLET FORMAT // PATHS TO BE INCLUDED REGARDLESS OF WALLET FORMAT

View File

@ -13,7 +13,10 @@ import {
ETC_TREZOR, ETC_TREZOR,
ETH_TESTNET, ETH_TESTNET,
EXP_DEFAULT, EXP_DEFAULT,
UBQ_DEFAULT UBQ_DEFAULT,
POA_DEFAULT,
TOMO_DEFAULT,
ELLA_DEFAULT
} from 'config/dpaths'; } from 'config/dpaths';
import { ConfigAction } from 'actions/config'; import { ConfigAction } from 'actions/config';
import { BlockExplorerConfig } from 'types/network'; import { BlockExplorerConfig } from 'types/network';
@ -22,17 +25,29 @@ import { StaticNetworksState as State } from './types';
// Must be a website that follows the ethplorer convention of /tx/[hash] and // Must be a website that follows the ethplorer convention of /tx/[hash] and
// address/[address] to generate the correct functions. // address/[address] to generate the correct functions.
// TODO: put this in utils / libs // TODO: put this in utils / libs
export function makeExplorer( interface ExplorerConfig {
name: string, name: string;
origin: string, origin: string;
addressPath: string = 'address' txPath?: string;
): BlockExplorerConfig { addressPath?: string;
blockPath?: string;
}
export function makeExplorer(expConfig: ExplorerConfig): BlockExplorerConfig {
const config: ExplorerConfig = {
// Defaults
txPath: 'tx',
addressPath: 'address',
blockPath: 'block',
...expConfig
};
return { return {
name, name: config.origin,
origin, origin: config.origin,
txUrl: hash => `${origin}/tx/${hash}`, txUrl: hash => `${config.origin}/${config.txPath}/${hash}`,
addressUrl: address => `${origin}/${addressPath}/${address}`, addressUrl: address => `${config.origin}/${config.addressPath}/${address}`,
blockUrl: blockNum => `${origin}/block/${blockNum}` blockUrl: blockNum => `${config.origin}/${config.blockPath}/${blockNum}`
}; };
} }
@ -49,7 +64,10 @@ export const INITIAL_STATE: State = {
chainId: 1, chainId: 1,
isCustom: false, isCustom: false,
color: '#007896', color: '#007896',
blockExplorer: makeExplorer('Etherscan', 'https://etherscan.io'), blockExplorer: makeExplorer({
name: 'Etherscan',
origin: 'https://etherscan.io'
}),
tokenExplorer: { tokenExplorer: {
name: ethPlorer, name: ethPlorer,
address: ETHTokenExplorer address: ETHTokenExplorer
@ -70,7 +88,10 @@ export const INITIAL_STATE: State = {
chainId: 3, chainId: 3,
isCustom: false, isCustom: false,
color: '#adc101', color: '#adc101',
blockExplorer: makeExplorer('Etherscan', 'https://ropsten.etherscan.io'), blockExplorer: makeExplorer({
name: 'Etherscan',
origin: 'https://ropsten.etherscan.io'
}),
tokens: require('config/tokens/ropsten.json'), tokens: require('config/tokens/ropsten.json'),
contracts: require('config/contracts/ropsten.json'), contracts: require('config/contracts/ropsten.json'),
isTestnet: true, isTestnet: true,
@ -87,7 +108,10 @@ export const INITIAL_STATE: State = {
chainId: 42, chainId: 42,
isCustom: false, isCustom: false,
color: '#adc101', color: '#adc101',
blockExplorer: makeExplorer('Etherscan', 'https://kovan.etherscan.io'), blockExplorer: makeExplorer({
name: 'Etherscan',
origin: 'https://kovan.etherscan.io'
}),
tokens: require('config/tokens/ropsten.json'), tokens: require('config/tokens/ropsten.json'),
contracts: require('config/contracts/ropsten.json'), contracts: require('config/contracts/ropsten.json'),
isTestnet: true, isTestnet: true,
@ -104,7 +128,10 @@ export const INITIAL_STATE: State = {
chainId: 4, chainId: 4,
isCustom: false, isCustom: false,
color: '#adc101', color: '#adc101',
blockExplorer: makeExplorer('Etherscan', 'https://rinkeby.etherscan.io'), blockExplorer: makeExplorer({
name: 'Etherscan',
origin: 'https://rinkeby.etherscan.io'
}),
tokens: require('config/tokens/rinkeby.json'), tokens: require('config/tokens/rinkeby.json'),
contracts: require('config/contracts/rinkeby.json'), contracts: require('config/contracts/rinkeby.json'),
isTestnet: true, isTestnet: true,
@ -121,7 +148,11 @@ export const INITIAL_STATE: State = {
chainId: 61, chainId: 61,
isCustom: false, isCustom: false,
color: '#669073', color: '#669073',
blockExplorer: makeExplorer('GasTracker', 'https://gastracker.io', 'addr'), blockExplorer: makeExplorer({
name: 'GasTracker',
origin: 'https://gastracker.io',
addressPath: 'addr'
}),
tokens: require('config/tokens/etc.json'), tokens: require('config/tokens/etc.json'),
contracts: require('config/contracts/etc.json'), contracts: require('config/contracts/etc.json'),
dPathFormats: { dPathFormats: {
@ -141,7 +172,10 @@ export const INITIAL_STATE: State = {
chainId: 8, chainId: 8,
isCustom: false, isCustom: false,
color: '#b37aff', color: '#b37aff',
blockExplorer: makeExplorer('Ubiqscan', 'https://ubiqscan.io/en'), blockExplorer: makeExplorer({
name: 'Ubiqscan',
origin: 'https://ubiqscan.io/en'
}),
tokens: require('config/tokens/ubq.json'), tokens: require('config/tokens/ubq.json'),
contracts: require('config/contracts/ubq.json'), contracts: require('config/contracts/ubq.json'),
dPathFormats: { dPathFormats: {
@ -161,7 +195,10 @@ export const INITIAL_STATE: State = {
chainId: 2, chainId: 2,
isCustom: false, isCustom: false,
color: '#673ab7', color: '#673ab7',
blockExplorer: makeExplorer('Gander', 'https://www.gander.tech'), blockExplorer: makeExplorer({
name: 'Gander',
origin: 'https://www.gander.tech'
}),
tokens: require('config/tokens/exp.json'), tokens: require('config/tokens/exp.json'),
contracts: require('config/contracts/exp.json'), contracts: require('config/contracts/exp.json'),
dPathFormats: { dPathFormats: {
@ -174,6 +211,76 @@ export const INITIAL_STATE: State = {
max: 20, max: 20,
initial: 2 initial: 2
} }
},
POA: {
name: 'POA',
unit: 'POA',
chainId: 99,
isCustom: false,
color: '#6d2eae',
blockExplorer: makeExplorer({
name: 'Etherchain Light',
origin: 'https://poaexplorer.com',
addressPath: 'address/search',
blockPath: 'blocks/block'
}),
tokens: [],
contracts: [],
dPathFormats: {
[SecureWalletName.TREZOR]: POA_DEFAULT,
[SecureWalletName.LEDGER_NANO_S]: POA_DEFAULT,
[InsecureWalletName.MNEMONIC_PHRASE]: POA_DEFAULT
},
gasPriceSettings: {
min: 0.1,
max: 10,
initial: 1
}
},
TOMO: {
name: 'TOMO',
unit: 'TOMO',
chainId: 40686,
isCustom: false,
color: '#6a488d',
blockExplorer: makeExplorer({
name: 'Tomochain Explorer',
origin: 'https://explorer.tomocoin.io/#'
}),
tokens: [],
contracts: [],
dPathFormats: {
[SecureWalletName.TREZOR]: TOMO_DEFAULT,
[SecureWalletName.LEDGER_NANO_S]: TOMO_DEFAULT,
[InsecureWalletName.MNEMONIC_PHRASE]: TOMO_DEFAULT
},
gasPriceSettings: {
min: 1,
max: 60,
initial: 20
}
},
ELLA: {
name: 'ELLA',
unit: 'ELLA',
chainId: 64,
isCustom: false,
color: '#046111',
blockExplorer: makeExplorer({
name: 'Ellaism Explorer',
origin: 'https://explorer.ellaism.org'
}),
tokens: [],
contracts: [],
dPathFormats: {
[SecureWalletName.TREZOR]: ELLA_DEFAULT,
[InsecureWalletName.MNEMONIC_PHRASE]: ELLA_DEFAULT
},
gasPriceSettings: {
min: 1,
max: 60,
initial: 20
}
} }
}; };

View File

@ -79,6 +79,27 @@ export const INITIAL_STATE: State = {
service: 'Expanse.tech', service: 'Expanse.tech',
lib: new RPCNode('https://node.expanse.tech/'), lib: new RPCNode('https://node.expanse.tech/'),
estimateGas: true estimateGas: true
},
poa: {
network: 'POA',
isCustom: false,
service: 'poa.network',
lib: new RPCNode('https://core.poa.network'),
estimateGas: true
},
tomo: {
network: 'TOMO',
isCustom: false,
service: 'tomocoin.io',
lib: new RPCNode('https://core.tomocoin.io'),
estimateGas: true
},
ella: {
network: 'ELLA',
isCustom: false,
service: 'ellaism.org',
lib: new RPCNode('https://jsonrpc.ellaism.org'),
estimateGas: true
} }
}; };

View File

@ -15,17 +15,17 @@ type DPathFormat =
export function getPaths(state: AppState, pathType: PathType): DPath[] { export function getPaths(state: AppState, pathType: PathType): DPath[] {
const paths = Object.values(getStaticNetworkConfigs(state)) const paths = Object.values(getStaticNetworkConfigs(state))
.reduce( .reduce((networkPaths: DPath[], { dPathFormats }): DPath[] => {
(networkPaths: DPath[], { dPathFormats }) => if (dPathFormats && dPathFormats[pathType]) {
dPathFormats ? [...networkPaths, dPathFormats[pathType]] : networkPaths, return [...networkPaths, dPathFormats[pathType] as DPath];
}
[] return networkPaths;
) }, [])
.concat(EXTRA_PATHS); .concat(EXTRA_PATHS);
return sortedUniq(paths); return sortedUniq(paths);
} }
export function getSingleDPath(state: AppState, format: DPathFormat): DPath { export function getSingleDPath(state: AppState, format: DPathFormat): DPath | undefined {
const network = getStaticNetworkConfig(state); const network = getStaticNetworkConfig(state);
if (!network) { if (!network) {
throw Error('No static network config loaded'); throw Error('No static network config loaded');

View File

@ -166,7 +166,7 @@ export function getDisabledWallets(state: AppState): DisabledWallets {
// Some wallets don't support some networks // Some wallets don't support some networks
addReason( addReason(
unSupportedWalletFormatsOnNetwork(state), unSupportedWalletFormatsOnNetwork(state),
`${network.name} does not support this wallet` `This wallet doesnt support the ${network.name} network`
); );
// Some wallets are unavailable offline // Some wallets are unavailable offline

View File

@ -1,6 +1,16 @@
import { StaticNetworksState, CustomNetworksState } from 'reducers/config/networks'; import { StaticNetworksState, CustomNetworksState } from 'reducers/config/networks';
type StaticNetworkIds = 'ETH' | 'Ropsten' | 'Kovan' | 'Rinkeby' | 'ETC' | 'UBQ' | 'EXP'; type StaticNetworkIds =
| 'ETH'
| 'Ropsten'
| 'Kovan'
| 'Rinkeby'
| 'ETC'
| 'UBQ'
| 'EXP'
| 'POA'
| 'TOMO'
| 'ELLA';
export interface BlockExplorerConfig { export interface BlockExplorerConfig {
name: string; name: string;
@ -24,8 +34,8 @@ interface NetworkContract {
} }
interface DPathFormats { interface DPathFormats {
trezor: DPath; trezor?: DPath;
ledgerNanoS: DPath; ledgerNanoS?: DPath;
mnemonicPhrase: DPath; mnemonicPhrase: DPath;
} }

View File

@ -41,7 +41,10 @@ declare enum StaticNodeId {
RIN_INFURA = 'rin_infura', RIN_INFURA = 'rin_infura',
ETC_EPOOL = 'etc_epool', ETC_EPOOL = 'etc_epool',
UBQ = 'ubq', UBQ = 'ubq',
EXP_TECH = 'exp_tech' EXP_TECH = 'exp_tech',
POA = 'poa',
TOMO = 'tomo',
ELLA = 'ella'
} }
type StaticNodeWithWeb3Id = StaticNodeId | 'web3'; type StaticNodeWithWeb3Id = StaticNodeId | 'web3';

View File

@ -14,7 +14,7 @@ Object {
"call": [Function], "call": [Function],
"createHeaders": [Function], "createHeaders": [Function],
"decorateRequest": [Function], "decorateRequest": [Function],
"endpoint": "https://node.expanse.tech/", "endpoint": "https://jsonrpc.ellaism.org",
"headers": Object {}, "headers": Object {},
}, },
"requests": RPCRequests {}, "requests": RPCRequests {},

View File

@ -1,91 +1,10 @@
import { configuredStore } from 'store'; import { configuredStore } from 'store';
import { web3SetNode, web3UnsetNode } from 'actions/config'; import { web3SetNode, web3UnsetNode } from 'actions/config';
import { staticNodes, INITIAL_STATE } from 'reducers/config/nodes/staticNodes'; import { staticNodes, INITIAL_STATE } from 'reducers/config/nodes/staticNodes';
import { EtherscanNode, InfuraNode, RPCNode } from 'libs/nodes';
import { Web3NodeConfig } from 'types/node'; import { Web3NodeConfig } from 'types/node';
import { Web3Service } from 'libs/nodes/web3'; import { Web3Service } from 'libs/nodes/web3';
configuredStore.getState(); configuredStore.getState();
const expectedInitialState = {
eth_mycrypto: {
network: 'ETH',
isCustom: false,
lib: new RPCNode('https://api.mycryptoapi.com/eth'),
service: 'MyCrypto',
estimateGas: true
},
eth_ethscan: {
network: 'ETH',
isCustom: false,
service: 'Etherscan.io',
lib: new EtherscanNode('https://api.etherscan.io/api'),
estimateGas: false
},
eth_infura: {
network: 'ETH',
isCustom: false,
service: 'infura.io',
lib: new InfuraNode('https://mainnet.infura.io/mycrypto'),
estimateGas: false
},
eth_blockscale: {
network: 'ETH',
isCustom: false,
lib: new RPCNode('https://api.dev.blockscale.net/dev/parity'),
service: 'Blockscale beta',
estimateGas: true
},
rop_infura: {
network: 'Ropsten',
isCustom: false,
service: 'infura.io',
lib: new InfuraNode('https://ropsten.infura.io/mycrypto'),
estimateGas: false
},
kov_ethscan: {
network: 'Kovan',
isCustom: false,
service: 'Etherscan.io',
lib: new EtherscanNode('https://kovan.etherscan.io/api'),
estimateGas: false
},
rin_ethscan: {
network: 'Rinkeby',
isCustom: false,
service: 'Etherscan.io',
lib: new EtherscanNode('https://rinkeby.etherscan.io/api'),
estimateGas: false
},
rin_infura: {
network: 'Rinkeby',
isCustom: false,
service: 'infura.io',
lib: new InfuraNode('https://rinkeby.infura.io/mycrypto'),
estimateGas: false
},
etc_epool: {
network: 'ETC',
isCustom: false,
service: 'Epool.io',
lib: new RPCNode('https://mewapi.epool.io'),
estimateGas: false
},
ubq: {
network: 'UBQ',
isCustom: false,
service: 'ubiqscan.io',
lib: new RPCNode('https://pyrus2.ubiqscan.io'),
estimateGas: true
},
exp_tech: {
network: 'EXP',
isCustom: false,
service: 'Expanse.tech',
lib: new RPCNode('https://node.expanse.tech/'),
estimateGas: true
}
};
const web3Id = 'web3'; const web3Id = 'web3';
const web3Node: Web3NodeConfig = { const web3Node: Web3NodeConfig = {
isCustom: false, isCustom: false,
@ -97,7 +16,7 @@ const web3Node: Web3NodeConfig = {
}; };
const expectedState = { const expectedState = {
initialState: expectedInitialState, initialState: staticNodes(undefined, {} as any),
setWeb3: { ...INITIAL_STATE, [web3Id]: web3Node }, setWeb3: { ...INITIAL_STATE, [web3Id]: web3Node },
unsetWeb3: { ...INITIAL_STATE } unsetWeb3: { ...INITIAL_STATE }
}; };