re-type repo

This commit is contained in:
HenryNguyen5 2018-01-29 20:41:59 -05:00
parent 86f8302d2b
commit 139cf405e7
73 changed files with 358 additions and 343 deletions

View File

@ -1,6 +1,5 @@
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
import { NodeConfig, CustomNodeConfig, NetworkConfig, CustomNetworkConfig } from 'config';
export type TToggleOfflineConfig = typeof toggleOfflineConfig;
export function toggleOfflineConfig(): interfaces.ToggleOfflineAction {
@ -25,14 +24,10 @@ export function changeLanguage(sign: string): interfaces.ChangeLanguageAction {
}
export type TChangeNode = typeof changeNode;
export function changeNode(
nodeSelection: string,
node: NodeConfig,
network: NetworkConfig
): interfaces.ChangeNodeAction {
export function changeNode(networkName: string, nodeName: string): interfaces.ChangeNodeAction {
return {
type: TypeKeys.CONFIG_NODE_CHANGE,
payload: { nodeSelection, nodeName, networkName }
payload: { networkName, nodeName }
};
}
@ -52,7 +47,9 @@ export function changeNodeIntent(payload: string): interfaces.ChangeNodeIntentAc
}
export type TAddCustomNode = typeof addCustomNode;
export function addCustomNode(payload: CustomNodeConfig): interfaces.AddCustomNodeAction {
export function addCustomNode(
payload: interfaces.AddCustomNodeAction['payload']
): interfaces.AddCustomNodeAction {
return {
type: TypeKeys.CONFIG_ADD_CUSTOM_NODE,
payload
@ -60,7 +57,9 @@ export function addCustomNode(payload: CustomNodeConfig): interfaces.AddCustomNo
}
export type TRemoveCustomNode = typeof removeCustomNode;
export function removeCustomNode(payload: CustomNodeConfig): interfaces.RemoveCustomNodeAction {
export function removeCustomNode(
payload: interfaces.RemoveCustomNodeAction['payload']
): interfaces.RemoveCustomNodeAction {
return {
type: TypeKeys.CONFIG_REMOVE_CUSTOM_NODE,
payload
@ -68,7 +67,9 @@ export function removeCustomNode(payload: CustomNodeConfig): interfaces.RemoveCu
}
export type TAddCustomNetwork = typeof addCustomNetwork;
export function addCustomNetwork(payload: CustomNetworkConfig): interfaces.AddCustomNetworkAction {
export function addCustomNetwork(
payload: interfaces.AddCustomNetworkAction['payload']
): interfaces.AddCustomNetworkAction {
return {
type: TypeKeys.CONFIG_ADD_CUSTOM_NETWORK,
payload
@ -77,7 +78,7 @@ export function addCustomNetwork(payload: CustomNetworkConfig): interfaces.AddCu
export type TRemoveCustomNetwork = typeof removeCustomNetwork;
export function removeCustomNetwork(
payload: CustomNetworkConfig
payload: interfaces.RemoveCustomNetworkAction['payload']
): interfaces.RemoveCustomNetworkAction {
return {
type: TypeKeys.CONFIG_REMOVE_CUSTOM_NETWORK,

View File

@ -1,6 +1,6 @@
import { TypeKeys } from './constants';
import { CustomNodeConfig } from 'config';
import { CustomNetworkConfig } from 'reducers/config/networks/typings';
import { CustomNodeConfig } from 'types/node';
import { CustomNetworkConfig } from 'types/network';
/*** Toggle Offline ***/
export interface ToggleOfflineAction {

View File

@ -1,6 +1,6 @@
import { Token } from 'config';
import * as interfaces from './actionTypes';
import { TypeKeys } from './constants';
import { Token } from 'types/network';
export type TAddCustomToken = typeof addCustomToken;
export function addCustomToken(payload: Token): interfaces.AddCustomTokenAction {

View File

@ -1,5 +1,6 @@
import { Token } from 'config';
import { TypeKeys } from './constants';
import { Token } from 'types/network';
/*** Add custom token ***/
export interface AddCustomTokenAction {
type: TypeKeys.CUSTOM_TOKEN_ADD;

View File

@ -1,5 +1,4 @@
import { Identicon, UnitDisplay } from 'components/ui';
import { NetworkConfig } from 'config';
import { IWallet, Balance, TrezorWallet, LedgerWallet } from 'libs/wallet';
import React from 'react';
import translate from 'translations';
@ -8,6 +7,7 @@ import Spinner from 'components/ui/Spinner';
import { getNetworkConfig } from 'selectors/config';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { NetworkConfig } from 'types/network';
interface OwnProps {
wallet: IWallet;
@ -66,7 +66,14 @@ class AccountInfo extends React.Component<Props, State> {
public render() {
const { network, balance } = this.props;
const { address, showLongBalance, confirmAddr } = this.state;
const { blockExplorer, tokenExplorer } = network;
let blockExplorer;
let tokenExplorer;
if (!network.isCustom) {
// this is kind of ugly but its the result of typeguards, maybe we can find a cleaner solution later on such as just dedicating it to a selector
blockExplorer = network.blockExplorer;
tokenExplorer = network.tokenExplorer;
}
const wallet = this.props.wallet as LedgerWallet | TrezorWallet;
return (
<div className="AccountInfo">

View File

@ -6,12 +6,12 @@ import { TFetchCCRates, fetchCCRates, rateSymbols } from 'actions/rates';
import { chain, flatMap } from 'lodash';
import { TokenBalance, getShownTokenBalances } from 'selectors/wallet';
import { Balance } from 'libs/wallet';
import { NetworkConfig } from 'config';
import './EquivalentValues.scss';
import { Wei } from 'libs/units';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { connect } from 'react-redux';
import { NetworkConfig } from 'types/network';
interface AllValue {
symbol: string;
@ -36,10 +36,11 @@ interface State {
interface StateProps {
balance: Balance;
network: NetworkConfig;
tokenBalances: TokenBalance[];
rates: AppState['rates']['rates'];
ratesError: AppState['rates']['ratesError'];
isOffline: AppState['config']['offline'];
isOffline: AppState['config']['meta']['offline'];
}
interface DispatchProps {
@ -67,7 +68,7 @@ class EquivalentValues extends React.Component<Props, State> {
public defaultOption(
balance: Balance,
tokenBalances: TokenBalance[],
network: NetworkConfig
network: StateProps['network']
): DefaultOption {
return {
label: 'All',
@ -251,7 +252,6 @@ class EquivalentValues extends React.Component<Props, State> {
this.requestedCurrencies = currencies;
}
}
function mapStateToProps(state: AppState): StateProps {
return {
balance: state.wallet.balance,
@ -259,7 +259,7 @@ function mapStateToProps(state: AppState): StateProps {
network: getNetworkConfig(state),
rates: state.rates.rates,
ratesError: state.rates.ratesError,
isOffline: state.config.offline
isOffline: getOffline(state)
};
}

View File

@ -1,9 +1,9 @@
import React from 'react';
import classnames from 'classnames';
import { Token } from 'config';
import { isPositiveIntegerOrZero, isValidETHAddress } from 'libs/validators';
import translate from 'translations';
import NewTabLink from 'components/ui/NewTabLink';
import { Token } from 'types/network';
import './AddCustomTokenForm.scss';
interface Props {

View File

@ -1,9 +1,9 @@
import React from 'react';
import translate from 'translations';
import { Token } from 'config';
import { TokenBalance } from 'selectors/wallet';
import AddCustomTokenForm from './AddCustomTokenForm';
import TokenRow from './TokenRow';
import { Token } from 'types/network';
interface Props {
allTokens: Token[];

View File

@ -13,12 +13,12 @@ import {
setWalletTokens,
TSetWalletTokens
} from 'actions/wallet';
import { getAllTokens } from 'selectors/config';
import { getAllTokens, getOffline } from 'selectors/config';
import { getTokenBalances, getWalletInst, getWalletConfig, TokenBalance } from 'selectors/wallet';
import { Token } from 'config';
import translate from 'translations';
import Balances from './Balances';
import Spinner from 'components/ui/Spinner';
import { Token } from 'types/network';
import './index.scss';
interface StateProps {
@ -29,7 +29,7 @@ interface StateProps {
tokensError: AppState['wallet']['tokensError'];
isTokensLoading: AppState['wallet']['isTokensLoading'];
hasSavedWalletTokens: AppState['wallet']['hasSavedWalletTokens'];
isOffline: AppState['config']['offline'];
isOffline: AppState['config']['meta']['offline'];
}
interface ActionProps {
addCustomToken: TAddCustomToken;
@ -118,7 +118,7 @@ function mapStateToProps(state: AppState): StateProps {
tokensError: state.wallet.tokensError,
isTokensLoading: state.wallet.isTokensLoading,
hasSavedWalletTokens: state.wallet.hasSavedWalletTokens,
isOffline: state.config.offline
isOffline: getOffline(state)
};
}

View File

@ -8,11 +8,12 @@ import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { getDecimal, getUnit } from 'selectors/transaction';
import { getNetworkConfig } from 'selectors/config';
import { NetworkConfig } from 'types/network';
interface StateProps {
unit: string;
decimal: number;
network: AppState['config']['network'];
network: NetworkConfig;
}
class AmountClass extends Component<StateProps> {

View File

@ -4,13 +4,14 @@ import { SerializedTransaction } from 'components/renderCbs';
import { UnitDisplay } from 'components/ui';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { getNetworkConfig } from 'selectors/config';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { NetworkConfig } from 'types/network';
import BN from 'bn.js';
interface Props {
rates: AppState['rates']['rates'];
network: AppState['config']['network'];
isOffline: AppState['config']['offline'];
network: NetworkConfig;
isOffline: AppState['config']['meta']['offline'];
}
class TransactionFeeClass extends React.Component<Props> {
@ -51,7 +52,7 @@ function mapStateToProps(state: AppState) {
return {
rates: state.rates.rates,
network: getNetworkConfig(state),
isOffline: state.config.offline
isOffline: getOffline(state)
};
}
export const TransactionFee = connect(mapStateToProps)(TransactionFeeClass);

View File

@ -1,11 +1,11 @@
import { NodeConfig } from 'config';
import React, { Component } from 'react';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { getNodeConfig } from 'selectors/config';
import { StaticNodeConfig } from 'types/node';
interface StateProps {
node: NodeConfig;
node: StaticNodeConfig;
}
class NodeClass extends Component<StateProps, {}> {

View File

@ -1,6 +1,6 @@
import { BlockExplorerConfig } from 'config';
import React from 'react';
import { translateRaw } from 'translations';
import { BlockExplorerConfig } from 'types/network';
export interface TransactionSucceededProps {
txHash: string;

View File

@ -4,7 +4,7 @@ import { AppState } from 'reducers';
import { getOffline } from 'selectors/config';
interface StateProps {
offline: AppState['config']['offline'];
offline: AppState['config']['meta']['offline'];
}
class OfflineBroadcastClass extends Component<StateProps> {
public render() {

View File

@ -16,13 +16,14 @@ import SimpleGas from './components/SimpleGas';
import AdvancedGas, { AdvancedOptions } from './components/AdvancedGas';
import './TXMetaDataPanel.scss';
import { getGasPrice } from 'selectors/transaction';
import { NetworkConfig } from 'types/network';
type SliderStates = 'simple' | 'advanced';
interface StateProps {
gasPrice: AppState['transaction']['fields']['gasPrice'];
offline: AppState['config']['offline'];
network: AppState['config']['network'];
offline: AppState['config']['meta']['offline'];
network: NetworkConfig;
}
interface DispatchProps {

View File

@ -27,7 +27,7 @@ interface OwnProps {
}
interface StateProps {
autoGasLimitEnabled: AppState['config']['autoGasLimit'];
autoGasLimitEnabled: AppState['config']['meta']['autoGasLimit'];
validGasPrice: boolean;
}

View File

@ -2,8 +2,9 @@ import React from 'react';
import BN from 'bn.js';
import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import { getNetworkConfig, getOffline } from 'selectors/config';
import { UnitDisplay } from 'components/ui';
import { NetworkConfig } from 'types/network';
import './FeeSummary.scss';
interface RenderData {
@ -19,8 +20,8 @@ interface Props {
gasPrice: AppState['transaction']['fields']['gasPrice'];
gasLimit: AppState['transaction']['fields']['gasLimit'];
rates: AppState['rates']['rates'];
network: AppState['config']['network'];
isOffline: AppState['config']['offline'];
network: NetworkConfig;
isOffline: AppState['config']['meta']['offline'];
// Component props
render(data: RenderData): React.ReactElement<string> | string;
}
@ -73,7 +74,7 @@ function mapStateToProps(state: AppState) {
gasLimit: state.transaction.fields.gasLimit,
rates: state.rates.rates,
network: getNetworkConfig(state),
isOffline: state.config.offline
isOffline: getOffline(state)
};
}

View File

@ -8,6 +8,7 @@ import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { getUnit } from 'selectors/transaction';
import { getNetworkConfig } from 'selectors/config';
import { NetworkConfig } from 'types/network';
interface DispatchProps {
setUnitMeta: TSetUnitMeta;
@ -18,7 +19,7 @@ interface StateProps {
tokens: TokenBalance[];
allTokens: MergedToken[];
showAllTokens?: boolean;
network: AppState['config']['network'];
network: NetworkConfig;
}
const StringDropdown = Dropdown as new () => Dropdown<string>;

View File

@ -45,11 +45,10 @@ import {
InsecureWalletName,
MiscWalletName,
WalletName,
isWeb3NodeAvailable,
knowledgeBaseURL
} from 'config';
import { unSupportedWalletFormatsOnNetwork } from 'utils/network';
import { getNetworkConfig } from '../../selectors/config';
import { getNetworkConfig, getOffline } from '../../selectors/config';
interface OwnProps {
hidden?: boolean;
@ -443,7 +442,7 @@ function mapStateToProps(state: AppState, ownProps: Props) {
: networkDisabledFormats;
return {
computedDisabledWallets,
offline: state.config.offline,
offline: getOffline(state),
isWalletPending: state.wallet.isWalletPending,
isPasswordPending: state.wallet.isPasswordPending
};

View File

@ -8,7 +8,6 @@ import {
} from 'actions/deterministicWallets';
import Modal, { IButton } from 'components/ui/Modal';
import { AppState } from 'reducers';
import { NetworkConfig } from 'config';
import { isValidPath } from 'libs/validators';
import React from 'react';
import { connect } from 'react-redux';
@ -16,7 +15,7 @@ import { getNetworkConfig } from 'selectors/config';
import { getTokens, MergedToken } from 'selectors/wallet';
import { UnitDisplay } from 'components/ui';
import './DeterministicWalletsModal.scss';
import { DPath } from 'config/dpaths';
import { StaticNetworkConfig } from 'types/network';
import Select from 'react-select';
const WALLETS_PER_PAGE = 5;
@ -34,7 +33,7 @@ interface Props {
// Redux state
wallets: AppState['deterministicWallets']['wallets'];
desiredToken: AppState['deterministicWallets']['desiredToken'];
network: NetworkConfig;
network: StaticNetworkConfig;
tokens: MergedToken[];
// Redux actions

View File

@ -9,7 +9,6 @@ import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import { SecureWalletName } from 'config';
import { DPath } from 'config/dpaths';
import { getPaths, getSingleDPath } from 'utils/network';
interface OwnProps {

View File

@ -7,7 +7,6 @@ import { InsecureWalletName } from 'config';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import { connect } from 'react-redux';
import { DPath } from 'config/dpaths';
import { getPaths, getSingleDPath } from 'utils/network';
interface Props {

View File

@ -9,7 +9,6 @@ import { getNetworkConfig } from 'selectors/config';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
import { SecureWalletName } from 'config';
import { DPath } from 'config/dpaths';
import { getPaths, getSingleDPath } from 'utils/network';
//todo: conflicts with comment in walletDecrypt -> onUnlock method

View File

@ -85,7 +85,7 @@ export default UnitDisplay;
* Circumvents typescript issue with union props on connected components.
*/
interface OfflineProps {
offline: AppState['config']['offline'];
offline: AppState['config']['meta']['offline'];
children: React.ReactElement<string>;
}

View File

@ -1,8 +1,3 @@
export interface DPath {
label: string;
value: string; // TODO determine method for more precise typing for path
}
export const ETH_DEFAULT: DPath = {
label: 'Default (ETH)',
value: "m/44'/60'/0'/0"

View File

@ -1,3 +1,2 @@
export * from './networks';
export * from './data';
export * from './bity';

View File

@ -17,32 +17,21 @@ import { AlphaAgreement, Footer, Header } from 'components';
import { AppState } from 'reducers';
import Notifications from './Notifications';
import OfflineTab from './OfflineTab';
import {
getOffline,
getLanguageSelection,
getCustomNodeConfigs,
getCustomNetworkConfigs,
getLatestBlock,
isNodeChanging
} from 'selectors/config';
import { NodeConfig, CustomNodeConfig } from 'types/node';
import { CustomNetworkConfig } from 'types/network';
interface ReduxProps {
languageSelection: AppState['config']['languageSelection'];
node: AppState['config']['node'];
nodeSelection: AppState['config']['nodeSelection'];
isChangingNode: AppState['config']['isChangingNode'];
isOffline: AppState['config']['offline'];
customNodes: AppState['config']['customNodes'];
customNetworks: AppState['config']['customNetworks'];
latestBlock: AppState['config']['latestBlock'];
}
interface ActionProps {
changeLanguage: TChangeLanguage;
changeNodeIntent: TChangeNodeIntent;
addCustomNode: TAddCustomNode;
removeCustomNode: TRemoveCustomNode;
addCustomNetwork: TAddCustomNetwork;
setGasPriceField: TSetGasPriceField;
}
type Props = {
interface Props {
isUnavailableOffline?: boolean;
children: string | React.ReactElement<string> | React.ReactElement<string>[];
} & ReduxProps &
ActionProps;
}
class TabSection extends Component<Props, {}> {
public render() {
@ -50,38 +39,9 @@ class TabSection extends Component<Props, {}> {
isUnavailableOffline,
children,
// APP
node,
nodeSelection,
isChangingNode,
isOffline,
languageSelection,
customNodes,
customNetworks,
latestBlock,
setGasPriceField,
changeLanguage,
changeNodeIntent,
addCustomNode,
removeCustomNode,
addCustomNetwork
isOffline
} = this.props;
const headerProps = {
languageSelection,
node,
nodeSelection,
isChangingNode,
isOffline,
customNodes,
customNetworks,
changeLanguage,
changeNodeIntent,
setGasPriceField,
addCustomNode,
removeCustomNode,
addCustomNetwork
};
return (
<div className="page-layout">
<main>
@ -102,20 +62,13 @@ function mapStateToProps(state: AppState): ReduxProps {
return {
node: state.config.node,
nodeSelection: state.config.nodeSelection,
isChangingNode: state.config.isChangingNode,
isOffline: state.config.offline,
languageSelection: state.config.languageSelection,
customNodes: state.config.customNodes,
customNetworks: state.config.customNetworks,
latestBlock: state.config.latestBlock
isChangingNode: isNodeChanging(state),
isOffline: getOffline(state),
languageSelection: getLanguageSelection(state),
customNodes: getCustomNodeConfigs(state),
customNetworks: getCustomNetworkConfigs(state),
latestBlock: getLatestBlock(state)
};
}
export default connect(mapStateToProps, {
setGasPriceField: dSetGasPriceField,
changeLanguage: dChangeLanguage,
changeNodeIntent: dChangeNodeIntent,
addCustomNode: dAddCustomNode,
removeCustomNode: dRemoveCustomNode,
addCustomNetwork: dAddCustomNetwork
})(TabSection);
export default connect(mapStateToProps, {})(TabSection);

View File

@ -4,7 +4,6 @@ import './InteractExplorer.scss';
import { TShowNotification, showNotification } from 'actions/notifications';
import { getNodeLib } from 'selectors/config';
import { getTo, getDataExists } from 'selectors/transaction';
import { INode } from 'libs/nodes/INode';
import { GenerateTransaction } from 'components/GenerateTransaction';
import { AppState } from 'reducers';
import { connect } from 'react-redux';
@ -12,9 +11,11 @@ import { Fields } from './components';
import { setDataField, TSetDataField } from 'actions/transaction';
import { Data } from 'libs/units';
import Select from 'react-select';
import { Web3Node } from 'libs/nodes';
import RpcNode from 'libs/nodes/rpc';
interface StateProps {
nodeLib: INode;
nodeLib: RpcNode | Web3Node;
to: AppState['transaction']['fields']['to'];
dataExists: boolean;
}

View File

@ -1,12 +1,12 @@
import React, { Component } from 'react';
import translate from 'translations';
import { NetworkContract } from 'config';
import { getNetworkContracts } from 'selectors/config';
import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { isValidETHAddress, isValidAbiJson } from 'libs/validators';
import classnames from 'classnames';
import Select from 'react-select';
import { NetworkContract } from 'types/network';
interface ContractOption {
name: string;

View File

@ -12,7 +12,6 @@ import {
ICurrentValue
} from 'selectors/transaction/current';
import BN from 'bn.js';
import { NetworkConfig } from 'config';
import { validNumber, validDecimal } from 'libs/validators';
import { getGasLimit } from 'selectors/transaction';
import { AddressField, AmountField, TXMetaDataPanel } from 'components';
@ -21,6 +20,7 @@ import { buildEIP681EtherRequest, buildEIP681TokenRequest } from 'libs/values';
import { getNetworkConfig, getSelectedTokenContractAddress } from 'selectors/config';
import './RequestPayment.scss';
import { reset, TReset, setCurrentTo, TSetCurrentTo } from 'actions/transaction';
import { NetworkConfig } from 'types/network';
interface OwnProps {
wallet: AppState['wallet']['inst'];
@ -31,7 +31,7 @@ interface StateProps {
currentTo: ICurrentTo;
currentValue: ICurrentValue;
gasLimit: SetGasLimitFieldAction['payload'];
networkConfig: NetworkConfig | undefined;
networkConfig: NetworkConfig;
decimal: number;
tokenContractAddress: string;
}

View File

@ -17,6 +17,7 @@ import SubTabs, { Tab } from 'components/SubTabs';
import { getNetworkConfig } from 'selectors/config';
import { isNetworkUnit } from 'utils/network';
import { RouteNotFound } from 'components/RouteNotFound';
import { NetworkConfig } from 'types/network';
const Send = () => (
<React.Fragment>
@ -27,7 +28,7 @@ const Send = () => (
interface StateProps {
wallet: AppState['wallet']['inst'];
network: AppState['config']['network'];
network: NetworkConfig;
}
type Props = StateProps & RouteComponentProps<{}>;

View File

@ -8,7 +8,7 @@ import { configureLiteSend, TConfigureLiteSend } from 'actions/swap';
import { connect } from 'react-redux';
import { AppState } from 'reducers';
import { shouldDisplayLiteSend } from 'selectors/swap';
import { NetworkConfig } from 'config';
import { NetworkConfig } from 'types/network';
interface DispatchProps {
configureLiteSend: TConfigureLiteSend;

View File

@ -56,6 +56,7 @@ import TabSection from 'containers/TabSection';
import { merge } from 'lodash';
import { RouteNotFound } from 'components/RouteNotFound';
import { Switch, Route, RouteComponentProps } from 'react-router';
import { getOffline } from 'selectors/config';
interface ReduxStateProps {
step: number;
@ -286,7 +287,7 @@ function mapStateToProps(state: AppState) {
bityOrderStatus: state.swap.bityOrderStatus,
shapeshiftOrderStatus: state.swap.shapeshiftOrderStatus,
paymentAddress: state.swap.paymentAddress,
isOffline: state.config.offline
isOffline: getOffline(state)
};
}

View File

@ -1,6 +1,6 @@
import { Token } from 'config';
import { Wei, TokenValue } from 'libs/units';
import { IHexStrTransaction } from 'libs/transaction';
import { Token } from 'types/network';
export interface TxObj {
to: string;

View File

@ -1,6 +1,6 @@
import RPCNode from '../rpc';
import RPCClient from '../rpc/client';
import { CustomNodeConfig } from 'config';
import { CustomNodeConfig } from 'types/node';
export default class CustomNode extends RPCNode {
constructor(config: CustomNodeConfig) {

View File

@ -1,4 +1,3 @@
import { Token } from 'config';
import ERC20 from 'libs/erc20';
import RPCRequests from '../rpc/requests';
import {
@ -10,6 +9,7 @@ import {
SendRawTxRequest,
GetCurrentBlockRequest
} from './types';
import { Token } from 'types/network';
export default class EtherscanRequests extends RPCRequests {
public sendRawTx(signedTx: string): SendRawTxRequest {

View File

@ -1,5 +1,4 @@
import BN from 'bn.js';
import { Token } from 'config';
import { IHexStrTransaction } from 'libs/transaction';
import { Wei, TokenValue } from 'libs/units';
import { stripHexPrefix } from 'libs/values';
@ -15,6 +14,7 @@ import {
isValidCurrentBlock,
isValidRawTxApi
} from '../../validators';
import { Token } from 'types/network';
export default class RpcNode implements INode {
public client: RPCClient;

View File

@ -1,4 +1,3 @@
import { Token } from 'config';
import ERC20 from 'libs/erc20';
import {
CallRequest,
@ -11,6 +10,8 @@ import {
} from './types';
import { hexEncodeData } from './utils';
import { TxObj } from '../INode';
import { Token } from 'types/network';
export default class RPCRequests {
public getNetVersion() {
return { method: 'net_version' };

View File

@ -1,7 +1,7 @@
import { Wei, toTokenBase } from 'libs/units';
import { addHexPrefix } from 'ethereumjs-util';
import BN from 'bn.js';
import { NetworkKeys } from 'config';
import { StaticNetworkNames } from 'types/network';
export function stripHexPrefix(value: string) {
return value.replace('0x', '');
@ -24,7 +24,7 @@ export function sanitizeHex(hex: string) {
return hex !== '' ? `0x${padLeftEven(hexStr)}` : '';
}
export function networkIdToName(networkId: string | number): NetworkKeys {
export function networkIdToName(networkId: string | number): StaticNetworkNames {
switch (networkId.toString()) {
case '1':
return 'ETH';

View File

@ -29,6 +29,9 @@ export default class Web3Wallet implements IFullWallet {
const state = configuredStore.getState();
const nodeLib: Web3Node | INode = getNodeLib(state);
if (!nodeLib) {
throw new Error('');
}
if (!isWeb3Node(nodeLib)) {
throw new Error('Web3 wallets can only be used with a Web3 node.');
}
@ -55,7 +58,7 @@ export default class Web3Wallet implements IFullWallet {
};
const state = configuredStore.getState();
const nodeLib: Web3Node | INode = getNodeLib(state);
const nodeLib: Web3Node | INode | undefined = getNodeLib(state);
if (!isWeb3Node(nodeLib)) {
throw new Error('Web3 wallets can only be used with a Web3 node.');

View File

@ -4,7 +4,7 @@ import {
CustomNetworkAction,
TypeKeys
} from 'actions/config';
import { CustomNetworkConfig } from 'reducers/config/networks/typings';
import { CustomNetworkConfig } from 'types/network';
// TODO: this doesn't accurately represent state, as
export interface State {

View File

@ -1,16 +1,18 @@
import { customNetworks, State as CustomNetworksState } from './customNetworks';
import { defaultNetworks, State as DefaultNetworksState } from './defaultNetworks';
import { staticNetworks, State as StaticNetworksState } from './staticNetworks';
import { selectedNetwork, State as SelectedNetworkState } from './selectedNetwork';
import { combineReducers } from 'redux';
export interface State {
interface State {
customNetworks: CustomNetworksState;
defaultNetworks: DefaultNetworksState;
staticNetworks: StaticNetworksState;
selectedNetwork: SelectedNetworkState;
}
export const networks = combineReducers<State>({
const networks = combineReducers<State>({
customNetworks,
defaultNetworks,
staticNetworks,
selectedNetwork
});
export { State, networks, StaticNetworksState, SelectedNetworkState, CustomNetworksState };

View File

@ -1,14 +1,14 @@
import { NodeAction, TypeKeys, ChangeNodeAction } from 'actions/config';
import { DefaultNetworkNames } from 'reducers/config/networks/typings';
import { INITIAL_STATE as INITIAL_NODE_STATE } from '../nodes/selectedNode'; // could probably consolidate this in the index file of 'nodes' to make it easier to import
import { INITIAL_STATE as INITIAL_DEFAULT_NODE_STATE } from '../nodes/defaultNodes';
import { NonWeb3NodeConfigs } from 'reducers/config/nodes/typings';
import { INITIAL_STATE as INITIAL_DEFAULT_NODE_STATE } from '../nodes/staticNodes';
import { NonWeb3NodeConfigs } from 'types/node';
import { StaticNetworkNames } from 'types/network';
const initalNode =
INITIAL_DEFAULT_NODE_STATE[INITIAL_NODE_STATE.nodeName as keyof NonWeb3NodeConfigs];
export type State = string | DefaultNetworkNames;
const INITIAL_STATE: State = initalNode.networkName;
export type State = string | StaticNetworkNames;
const INITIAL_STATE: State = initalNode.network;
const handleNodeChange = (_: State, { payload }: ChangeNodeAction) => payload.networkName;

View File

@ -9,14 +9,10 @@ import {
EXP_DEFAULT,
UBQ_DEFAULT
} from 'config/dpaths';
import {
DefaultNetworkConfig,
BlockExplorerConfig,
DefaultNetworkNames
} from 'reducers/config/networks/typings';
import { ConfigAction } from 'actions/config';
import { StaticNetworkNames, StaticNetworkConfig, BlockExplorerConfig } from 'types/network';
export type State = { [key in DefaultNetworkNames]: DefaultNetworkConfig };
export type State = { [key in StaticNetworkNames]: StaticNetworkConfig };
// Must be a website that follows the ethplorer convention of /tx/[hash] and
// address/[address] to generate the correct functions.
@ -34,6 +30,7 @@ const INITIAL_STATE: State = {
name: 'ETH',
unit: 'ETH',
chainId: 1,
isCustom: false,
color: '#0e97c0',
blockExplorer: makeExplorer('https://etherscan.io'),
tokenExplorer: {
@ -52,6 +49,7 @@ const INITIAL_STATE: State = {
name: 'Ropsten',
unit: 'ETH',
chainId: 3,
isCustom: false,
color: '#adc101',
blockExplorer: makeExplorer('https://ropsten.etherscan.io'),
tokens: require('./tokens/ropsten.json'),
@ -67,6 +65,7 @@ const INITIAL_STATE: State = {
name: 'Kovan',
unit: 'ETH',
chainId: 42,
isCustom: false,
color: '#adc101',
blockExplorer: makeExplorer('https://kovan.etherscan.io'),
tokens: require('./tokens/ropsten.json'),
@ -82,6 +81,7 @@ const INITIAL_STATE: State = {
name: 'Rinkeby',
unit: 'ETH',
chainId: 4,
isCustom: false,
color: '#adc101',
blockExplorer: makeExplorer('https://rinkeby.etherscan.io'),
tokens: require('./tokens/rinkeby.json'),
@ -97,6 +97,7 @@ const INITIAL_STATE: State = {
name: 'ETC',
unit: 'ETC',
chainId: 61,
isCustom: false,
color: '#669073',
blockExplorer: makeExplorer('https://gastracker.io'),
tokens: require('./tokens/etc.json'),
@ -111,6 +112,7 @@ const INITIAL_STATE: State = {
name: 'UBQ',
unit: 'UBQ',
chainId: 8,
isCustom: false,
color: '#b37aff',
blockExplorer: makeExplorer('https://ubiqscan.io/en'),
tokens: require('./tokens/ubq.json'),
@ -125,6 +127,7 @@ const INITIAL_STATE: State = {
name: 'EXP',
unit: 'EXP',
chainId: 2,
isCustom: false,
color: '#673ab7',
blockExplorer: makeExplorer('http://www.gander.tech'),
tokens: require('./tokens/exp.json'),
@ -137,7 +140,7 @@ const INITIAL_STATE: State = {
}
};
export const defaultNetworks = (state: State = INITIAL_STATE, action: ConfigAction) => {
export const staticNetworks = (state: State = INITIAL_STATE, action: ConfigAction) => {
switch (action.type) {
default:
return state;

View File

@ -1,10 +1,10 @@
import { CustomNodeConfig } from 'reducers/config/nodes/typings';
import {
TypeKeys,
CustomNodeAction,
AddCustomNodeAction,
RemoveCustomNodeAction
} from 'actions/config';
import { CustomNodeConfig } from 'types/node';
export interface State {
[customNodeId: string]: CustomNodeConfig;

View File

@ -1,12 +1,14 @@
import { customNodes, State as CustomNodeState } from './customNodes';
import { defaultNodes, State as DefaultNodeState } from './defaultNodes';
import { customNodes, State as CustomNodesState } from './customNodes';
import { staticNodes, State as StaticNodesState } from './staticNodes';
import { selectedNode, State as SelectedNodeState } from './selectedNode';
import { combineReducers } from 'redux';
export interface State {
customNodes: CustomNodeState;
defaultNodes: DefaultNodeState;
interface State {
customNodes: CustomNodesState;
staticNodes: StaticNodesState;
selectedNode: SelectedNodeState;
}
export const nodes = combineReducers<State>({ customNodes, defaultNodes, selectedNode });
const nodes = combineReducers<State>({ customNodes, staticNodes, selectedNode });
export { State, nodes, CustomNodesState, StaticNodesState, SelectedNodeState };

View File

@ -1,85 +1,85 @@
import { NonWeb3NodeConfigs, Web3NodeConfig } from 'reducers/config/nodes/typings';
import { EtherscanNode, InfuraNode, RPCNode } from 'libs/nodes';
import { ConfigAction } from 'actions/config';
import { Web3NodeConfig, NonWeb3NodeConfigs } from 'types/node';
export type State = NonWeb3NodeConfigs & Web3NodeConfig;
export const INITIAL_STATE: State = {
eth_mew: {
networkName: 'ETH',
network: 'ETH',
lib: new RPCNode('https://api.myetherapi.com/eth'),
service: 'MyEtherWallet',
estimateGas: true
},
eth_mycrypto: {
networkName: 'ETH',
network: 'ETH',
lib: new RPCNode('https://api.mycryptoapi.com/eth'),
service: 'MyCrypto',
estimateGas: true
},
eth_ethscan: {
networkName: 'ETH',
network: 'ETH',
service: 'Etherscan.io',
lib: new EtherscanNode('https://api.etherscan.io/api'),
estimateGas: false
},
eth_infura: {
networkName: 'ETH',
network: 'ETH',
service: 'infura.io',
lib: new InfuraNode('https://mainnet.infura.io/mew'),
estimateGas: false
},
rop_mew: {
networkName: 'Ropsten',
network: 'Ropsten',
service: 'MyEtherWallet',
lib: new RPCNode('https://api.myetherapi.com/rop'),
estimateGas: false
},
rop_infura: {
networkName: 'Ropsten',
network: 'Ropsten',
service: 'infura.io',
lib: new InfuraNode('https://ropsten.infura.io/mew'),
estimateGas: false
},
kov_ethscan: {
networkName: 'Kovan',
network: 'Kovan',
service: 'Etherscan.io',
lib: new EtherscanNode('https://kovan.etherscan.io/api'),
estimateGas: false
},
rin_ethscan: {
networkName: 'Rinkeby',
network: 'Rinkeby',
service: 'Etherscan.io',
lib: new EtherscanNode('https://rinkeby.etherscan.io/api'),
estimateGas: false
},
rin_infura: {
networkName: 'Rinkeby',
network: 'Rinkeby',
service: 'infura.io',
lib: new InfuraNode('https://rinkeby.infura.io/mew'),
estimateGas: false
},
etc_epool: {
networkName: 'ETC',
network: 'ETC',
service: 'Epool.io',
lib: new RPCNode('https://mewapi.epool.io'),
estimateGas: false
},
ubq: {
networkName: 'UBQ',
network: 'UBQ',
service: 'ubiqscan.io',
lib: new RPCNode('https://pyrus2.ubiqscan.io'),
estimateGas: true
},
exp_tech: {
networkName: 'EXP',
network: 'EXP',
service: 'Expanse.tech',
lib: new RPCNode('https://node.expanse.tech/'),
estimateGas: true
}
};
export const defaultNodes = (state: State = INITIAL_STATE, action: ConfigAction) => {
export const staticNodes = (state: State = INITIAL_STATE, action: ConfigAction) => {
switch (action.type) {
default:
return state;

View File

@ -1,46 +1,5 @@
import { RPCNode, Web3Node } from 'libs/nodes';
import { Web3Node } from 'libs/nodes';
import { networkIdToName } from 'libs/values';
import { DefaultNetworkNames } from 'reducers/config/networks/typings';
export interface CustomNodeConfig {
name: string;
url: string;
port: number;
network: string;
auth?: {
username: string;
password: string;
};
}
export interface DefaultNodeConfig {
networkName: DefaultNetworkNames;
lib: RPCNode | Web3Node;
service: string;
estimateGas?: boolean;
hidden?: boolean;
}
export enum DefaultNodeName {
ETH_MEW = 'eth_mew',
ETH_MYCRYPTO = 'eth_mycrypto',
ETH_ETHSCAN = 'eth_ethscan',
ETH_INFURA = 'eth_infura',
ROP_MEW = 'rop_mew',
ROP_INFURA = 'rop_infura',
KOV_ETHSCAN = 'kov_ethscan',
RIN_ETHSCAN = 'rin_ethscan',
RIN_INFURA = 'rin_infura',
ETC_EPOOL = 'etc_epool',
UBQ = 'ubq',
EXP_TECH = 'exp_tech'
}
export type NonWeb3NodeConfigs = { [key in DefaultNodeName]: DefaultNodeConfig };
export interface Web3NodeConfig {
web3?: DefaultNodeConfig;
}
/**
* TODO: Put this in a saga that runs on app mount
@ -85,13 +44,9 @@ export async function isWeb3NodeAvailable(): Promise<boolean> {
export const Web3Service = 'MetaMask / Mist';
export interface NodeConfigOverride extends DefaultNodeConfig {
networkName: any;
}
export async function initWeb3Node(): Promise<void> {
const { networkId, lib } = await setupWeb3Node();
const web3: NodeConfigOverride = {
const web3 = {
network: networkIdToName(networkId),
service: Web3Service,
lib,

View File

@ -4,7 +4,7 @@ import {
RemoveCustomTokenAction
} from 'actions/customTokens';
import { TypeKeys } from 'actions/customTokens/constants';
import { Token } from 'config';
import { Token } from 'types/network';
export type State = Token[];

View File

@ -10,14 +10,6 @@ import {
select,
race
} from 'redux-saga/effects';
import {
NODES,
NETWORKS,
NodeConfig,
CustomNodeConfig,
CustomNetworkConfig,
Web3Service
} from 'config';
import {
makeCustomNodeId,
getCustomNodeConfigFromId,
@ -47,13 +39,15 @@ import { translateRaw } from 'translations';
import { Web3Wallet } from 'libs/wallet';
import { TypeKeys as WalletTypeKeys } from 'actions/wallet/constants';
import { State as ConfigState, INITIAL_STATE as configInitialState } from 'reducers/config';
import { StaticNodeConfig, CustomNodeConfig } from 'types/node';
import { CustomNetworkConfig } from 'types/network';
export const getConfig = (state: AppState): ConfigState => state.config;
let hasCheckedOnline = false;
export function* pollOfflineStatus(): SagaIterator {
while (true) {
const node: NodeConfig = yield select(getNodeConfig);
const node: StaticNodeConfig = yield select(getNodeConfig);
const isOffline: boolean = yield select(getOffline);
// If our offline state disagrees with the browser, run a check
@ -121,7 +115,7 @@ export function* reload(): SagaIterator {
export function* handleNodeChangeIntent(action: ChangeNodeIntentAction): SagaIterator {
const currentNode: string = yield select(getNodeName);
const currentConfig: NodeConfig = yield select(getNodeConfig);
const currentConfig: StaticNodeConfig = yield select(getNodeConfig);
const customNets: CustomNetworkConfig[] = yield select(getCustomNetworkConfigs);
const currentNetwork =
getNetworkConfigFromId(currentConfig.network, customNets) || NETWORKS[currentConfig.network];
@ -233,13 +227,13 @@ export function* unsetWeb3Node(): SagaIterator {
return;
}
const nodeConfig: NodeConfig = yield select(getNodeConfig);
const nodeConfig: StaticNodeConfig = yield select(getNodeConfig);
const newNode = equivalentNodeOrDefault(nodeConfig);
yield put(changeNodeIntent(newNode));
}
export const equivalentNodeOrDefault = (nodeConfig: NodeConfig) => {
export const equivalentNodeOrDefault = (nodeConfig: StaticNodeConfig) => {
const node = Object.keys(NODES)
.filter(key => key !== 'web3')
.reduce((found, key) => {

View File

@ -5,7 +5,6 @@ import {
updateDeterministicWallet
} from 'actions/deterministicWallets';
import { showNotification } from 'actions/notifications';
import { Token } from 'config';
import { publicToAddress, toChecksumAddress } from 'ethereumjs-util';
import HDKey from 'hdkey';
import { INode } from 'libs/nodes/INode';
@ -16,6 +15,7 @@ import { getDesiredToken, getWallets } from 'selectors/deterministicWallets';
import { getTokens } from 'selectors/wallet';
import translate from 'translations';
import { TokenValue } from 'libs/units';
import { Token } from 'types/network';
export function* getDeterministicWallets(action: GetDeterministicWalletsAction): SagaIterator {
const { seed, dPath, publicKey, chainCode, limit, offset } = action.payload;

View File

@ -12,9 +12,9 @@ import {
TypeKeys as TK
} from 'actions/transaction';
import Tx from 'ethereumjs-tx';
import { NetworkConfig } from 'config';
import { SagaIterator } from 'redux-saga';
import { showNotification } from 'actions/notifications';
import { StaticNetworkConfig } from 'types/network';
interface IFullWalletAndTransaction {
wallet: IFullWallet;
@ -49,7 +49,7 @@ function* getWalletAndTransaction(
throw Error('Could not get wallet instance to sign transaction');
}
// get the chainId
const { chainId }: NetworkConfig = yield select(getNetworkConfig);
const { chainId }: StaticNetworkConfig = yield select(getNetworkConfig);
// get the rest of the transaction parameters
partialTx._chainId = chainId;

View File

@ -1,6 +1,5 @@
import { apply, select, call } from 'redux-saga/effects';
import { AppState } from 'reducers';
import { Token } from 'config';
import { INode } from 'libs/nodes/INode';
import { IWallet, WalletConfig } from 'libs/wallet';
import { TokenBalance } from 'selectors/wallet';
@ -8,6 +7,7 @@ import { getCustomTokens } from 'selectors/customTokens';
import { getNodeLib } from 'selectors/config';
import { loadWalletConfig } from 'utils/localStorage';
import { TokenBalanceLookup } from './wallet';
import { Token } from 'types/network';
export function* getTokenBalances(wallet: IWallet, tokens: Token[]) {
const node: INode = yield select(getNodeLib);

View File

@ -36,7 +36,6 @@ import {
Web3Wallet,
WalletConfig
} from 'libs/wallet';
import { NODES, initWeb3Node, Token } from 'config';
import { SagaIterator, delay, Task } from 'redux-saga';
import { apply, call, fork, put, select, takeEvery, take, cancel } from 'redux-saga/effects';
import { getNodeLib, getAllTokens, getOffline } from 'selectors/config';
@ -51,6 +50,7 @@ import translate from 'translations';
import Web3Node, { isWeb3Node } from 'libs/nodes/web3';
import { loadWalletConfig, saveWalletConfig } from 'utils/localStorage';
import { getTokenBalances, filterScannedTokenBalances } from './helpers';
import { Token } from 'types/network';
export interface TokenBalanceLookup {
[symbol: string]: TokenBalance;

View File

@ -1,41 +1,50 @@
import { AppState } from 'reducers';
import { getConfig } from 'selectors/config';
import {
DefaultNetworkConfig,
CustomNetworkConfig,
DefaultNetworkNames,
StaticNetworkConfig,
StaticNetworkNames,
NetworkContract
} from 'reducers/config/networks/typings';
} from 'types/network';
export const getNetworks = (state: AppState) => getConfig(state).networks;
export const isCurrentNetworkDefault = (state: AppState): DefaultNetworkConfig | undefined => {
const { defaultNetworks, selectedNetwork } = getNetworks(state);
const isDefaultNetworkName = (networkName: string): networkName is DefaultNetworkNames =>
Object.keys(defaultNetworks).includes(networkName);
export const getStaticNetworkNames = (state: AppState): StaticNetworkNames[] =>
Object.keys(getNetworks(state).staticNetworks) as StaticNetworkNames[];
export const getStaticNetworkConfig = (state: AppState): StaticNetworkConfig | undefined => {
const { staticNetworks, selectedNetwork } = getNetworks(state);
const isDefaultNetworkName = (networkName: string): networkName is StaticNetworkNames =>
Object.keys(staticNetworks).includes(networkName);
const defaultNetwork = isDefaultNetworkName(selectedNetwork)
? defaultNetworks[selectedNetwork]
? staticNetworks[selectedNetwork]
: undefined;
return defaultNetwork;
};
export const isCurrentNetworkCustom = (state: AppState): CustomNetworkConfig | undefined => {
export const getCustomNetworkConfig = (state: AppState): CustomNetworkConfig | undefined => {
const { customNetworks, selectedNetwork } = getNetworks(state);
const customNetwork = customNetworks[selectedNetwork];
return customNetwork;
};
export const getNetworkConfig = (
state: AppState
): DefaultNetworkConfig | CustomNetworkConfig | undefined =>
isCurrentNetworkDefault(state) || isCurrentNetworkCustom(state);
export const getNetworkConfig = (state: AppState): StaticNetworkConfig | CustomNetworkConfig => {
const config = getStaticNetworkConfig(state) || getCustomNetworkConfig(state);
if (!config) {
const { selectedNetwork } = getNetworks(state);
throw Error(
`No network config found for ${selectedNetwork} in either static or custom networks`
);
}
return config;
};
export const getNetworkContracts = (state: AppState): NetworkContract[] | null => {
const network = isCurrentNetworkDefault(state);
const network = getStaticNetworkConfig(state);
return network ? network.contracts : [];
};
export const getCustomNetworkConfigs = (state: AppState): CustomNetworkConfig[] => {
const { customNetworks } = getNetworks(state);
return Object.values(customNetworks);
};
export const getCustomNetworkConfigs = (state: AppState) => getNetworks(state).customNetworks;
export const getStaticNetworkConfigs = (state: AppState) => getNetworks(state).staticNetworks;

View File

@ -1,40 +1,43 @@
import { AppState } from 'reducers';
import { getConfig } from 'selectors/config';
import {
DefaultNodeConfig,
DefaultNodeName,
CustomNodeConfig
} from 'reducers/config/nodes/typings';
import { INode } from 'libs/nodes/INode';
import { getConfig, getStaticNetworkConfigs } from 'selectors/config';
import { CustomNodeConfig, StaticNodeConfig, StaticNodeName } from 'types/node';
export const getNodes = (state: AppState) => getConfig(state).nodes;
export const isCurrentNodeDefault = (state: AppState): DefaultNodeConfig | undefined => {
const { defaultNodes, selectedNode: { nodeName } } = getNodes(state);
export const getStaticNodeConfig = (state: AppState): StaticNodeConfig | undefined => {
const { staticNodes, selectedNode: { nodeName } } = getNodes(state);
if (nodeName === undefined) {
return nodeName;
}
const isDefaultNodeName = (networkName: string): networkName is DefaultNodeName =>
Object.keys(defaultNodes).includes(networkName);
const isStaticNodeName = (networkName: string): networkName is StaticNodeName =>
Object.keys(staticNodes).includes(networkName);
const defaultNetwork = isDefaultNodeName(nodeName) ? defaultNodes[nodeName] : undefined;
const defaultNetwork = isStaticNodeName(nodeName) ? staticNodes[nodeName] : undefined;
return defaultNetwork;
};
export const isCurrentNetworkCustom = (state: AppState): CustomNodeConfig | undefined => {
export const getCustomNodeConfig = (state: AppState): CustomNodeConfig | undefined => {
const { customNodes, selectedNode: { nodeName } } = getNodes(state);
if (nodeName === undefined) {
return nodeName;
}
const customNetwork = customNodes[nodeName];
return customNetwork;
const customNode = customNodes[nodeName];
return customNode;
};
export function getCustomNodeConfigs(state: AppState): CustomNodeConfig[] {
return Object.values(getNodes(state).customNodes);
export function getCustomNodeConfigs(state: AppState) {
return getNodes(state).customNodes;
}
export function getStaticNodes(state: AppState) {
return getNodes(state).staticNodes;
}
export function isNodeChanging(state): boolean {
return getNodes(state).selectedNode.pending;
}
export function getNodeName(state: AppState): string | undefined {
@ -45,11 +48,45 @@ export function getIsWeb3Node(state: AppState): boolean {
return getNodeName(state) === 'web3';
}
export function getNodeConfig(state: AppState): DefaultNodeConfig | CustomNodeConfig | undefined {
return isCurrentNodeDefault(state) || isCurrentNetworkCustom(state);
export function getNodeConfig(state: AppState): StaticNodeConfig | CustomNodeConfig | undefined {
const config = getStaticNodeConfig(state) || getCustomNodeConfig(state);
/*
if (!config) {
const { selectedNode } = getNodes(state);
throw Error(
`No node config found for ${selectedNode.nodeName} in either static or custom nodes`
);
}*/
return config;
}
export function getNodeLib(state: AppState): INode | undefined {
const config = isCurrentNodeDefault(state);
return config ? config.lib : undefined;
export function getNodeLib(state: AppState) {
const config = getStaticNodeConfig(state);
if (!config) {
throw Error('No node lib found when trying to select from state');
}
return config.lib;
}
interface NodeOption {
value: string;
name: { networkName?: string; service: string };
color?: string;
hidden?: boolean;
}
export function getStaticNodeOptions(state: AppState) {
const staticNetworkConfigs = getStaticNetworkConfigs(state);
Object.entries(getStaticNodes(state)).map(
([nodeName, nodeConfig]: [string, StaticNodeConfig]) => {
const networkName = nodeConfig.network;
const associatedNetwork = staticNetworkConfigs[networkName];
return {
value: nodeName,
name: { networkName, service: nodeConfig.service },
color: associatedNetwork.color,
hidden: nodeConfig.hidden
};
}
);
}

View File

@ -2,11 +2,11 @@ import { AppState } from 'reducers';
import { getUnit } from 'selectors/transaction/meta';
import { isEtherUnit } from 'libs/units';
import { SHAPESHIFT_TOKEN_WHITELIST } from 'api/shapeshift';
import { isCurrentNetworkDefault } from 'selectors/config';
import { Token } from 'reducers/config/networks/typings';
import { getStaticNetworkConfig } from 'selectors/config';
import { Token } from 'types/network';
export function getNetworkTokens(state: AppState): Token[] {
const network = isCurrentNetworkDefault(state);
const network = getStaticNetworkConfig(state);
return network ? network.tokens : [];
}

View File

@ -1,9 +1,9 @@
import { TokenValue, Wei } from 'libs/units';
import { Token } from 'config';
import { AppState } from 'reducers';
import { getNetworkConfig } from 'selectors/config';
import { getStaticNetworkConfig } from 'selectors/config';
import { IWallet, Web3Wallet, LedgerWallet, TrezorWallet, WalletConfig } from 'libs/wallet';
import { isEtherTransaction, getUnit } from './transaction';
import { Token } from 'types/network';
export function getWalletInst(state: AppState): IWallet | null | undefined {
return state.wallet.inst;
@ -30,7 +30,7 @@ export type MergedToken = Token & {
};
export function getTokens(state: AppState): MergedToken[] {
const network = getNetworkConfig(state);
const network = getStaticNetworkConfig(state);
const tokens: Token[] = network ? network.tokens : [];
return tokens.concat(
state.customTokens.map((token: Token) => {

View File

@ -1,29 +1,28 @@
import {
CustomNetworkConfig,
DPathFormats,
InsecureWalletName,
NetworkConfig,
NETWORKS,
SecureWalletName,
WalletName,
walletNames
} from 'config';
import { DPath, EXTRA_PATHS } from 'config/dpaths';
import { InsecureWalletName, SecureWalletName, WalletName, walletNames } from 'config';
import { EXTRA_PATHS } from 'config/dpaths';
import sortedUniq from 'lodash/sortedUniq';
import difference from 'lodash/difference';
import {
CustomNetworkConfig,
StaticNetworkConfig,
NetworkConfig,
DPathFormats
} from 'types/network';
export function makeCustomNetworkId(config: CustomNetworkConfig): string {
return config.chainId ? `${config.chainId}` : `${config.name}:${config.unit}`;
}
export function makeNetworkConfigFromCustomConfig(config: CustomNetworkConfig): NetworkConfig {
export function makeNetworkConfigFromCustomConfig(
config: CustomNetworkConfig
): StaticNetworkConfig {
// TODO - re-enable this block and classify customConfig after user-inputted dPaths are implemented
// -------------------------------------------------
// this still provides the type safety we want
// as we know config coming in is CustomNetworkConfig
// meaning name will be a string
// then we cast it as any to keep it as a network key
// interface Override extends NetworkConfig {
// interface Override extends StaticNetworkConfig {
// name: any;
// }
// -------------------------------------------------
@ -43,7 +42,7 @@ export function makeNetworkConfigFromCustomConfig(config: CustomNetworkConfig):
export function getNetworkConfigFromId(
id: string,
configs: CustomNetworkConfig[]
): NetworkConfig | undefined {
): StaticNetworkConfig | undefined {
if (NETWORKS[id]) {
return NETWORKS[id];
}

View File

@ -1,5 +1,5 @@
import { CustomNode } from 'libs/nodes';
import { NODES, NodeConfig, CustomNodeConfig } from 'config';
import { CustomNodeConfig, StaticNodeConfig } from 'types/node';
export function makeCustomNodeId(config: CustomNodeConfig): string {
return `${config.url}:${config.port}`;
@ -15,7 +15,7 @@ export function getCustomNodeConfigFromId(
export function getNodeConfigFromId(
id: string,
configs: CustomNodeConfig[]
): NodeConfig | undefined {
): StaticNodeConfig | undefined {
if (NODES[id]) {
return NODES[id];
}
@ -26,8 +26,8 @@ export function getNodeConfigFromId(
}
}
export function makeNodeConfigFromCustomConfig(config: CustomNodeConfig): NodeConfig {
interface Override extends NodeConfig {
export function makeNodeConfigFromCustomConfig(config: CustomNodeConfig): StaticNodeConfig {
interface Override extends StaticNodeConfig {
network: any;
}

View File

@ -1,4 +1,4 @@
import { Token } from 'config';
import { Token } from 'types/network';
export function dedupeCustomTokens(networkTokens: Token[], customTokens: Token[]): Token[] {
if (!customTokens.length) {

4
shared/types/hardware-wallets.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
interface DPath {
label: string;
value: string; // TODO determine method for more precise typing for path
}

View File

@ -1,35 +1,36 @@
import { DPath } from 'config/dpaths';
import { StaticNetworksState, CustomNetworksState } from 'reducers/config/networks';
export type DefaultNetworkNames = 'ETH' | 'Ropsten' | 'Kovan' | 'Rinkeby' | 'ETC' | 'UBQ' | 'EXP';
type StaticNetworkNames = 'ETH' | 'Ropsten' | 'Kovan' | 'Rinkeby' | 'ETC' | 'UBQ' | 'EXP';
export interface BlockExplorerConfig {
interface BlockExplorerConfig {
origin: string;
txUrl(txHash: string): string;
addressUrl(address: string): string;
}
export interface Token {
interface Token {
address: string;
symbol: string;
decimal: number;
error?: string | null;
}
export interface NetworkContract {
name: DefaultNetworkNames;
interface NetworkContract {
name: StaticNetworkNames;
address?: string;
abi: string;
}
export interface DPathFormats {
interface DPathFormats {
trezor: DPath;
ledgerNanoS: DPath;
mnemonicPhrase: DPath;
}
export interface DefaultNetworkConfig {
interface StaticNetworkConfig {
// TODO really try not to allow strings due to custom networks
name: DefaultNetworkNames;
isCustom: false; // used for type guards
name: StaticNetworkNames;
unit: string;
color?: string;
blockExplorer?: BlockExplorerConfig;
@ -44,9 +45,13 @@ export interface DefaultNetworkConfig {
isTestnet?: boolean;
}
export interface CustomNetworkConfig {
interface CustomNetworkConfig {
isCustom: true; // used for type guards
isTestnet?: boolean;
name: string;
unit: string;
chainId: number;
dPathFormats: DPathFormats | null;
}
type NetworkConfig = StaticNetworksState[StaticNetworkNames] | CustomNetworksState[string];

45
shared/types/node.d.ts vendored Normal file
View File

@ -0,0 +1,45 @@
import { RPCNode, Web3Node } from 'libs/nodes';
import { StaticNetworkNames } from './network';
import { StaticNodesState, CustomNodesState } from 'reducers/config/nodes';
interface CustomNodeConfig {
name: string;
url: string;
port: number;
network: string;
auth?: {
username: string;
password: string;
};
}
interface StaticNodeConfig {
network: StaticNetworkNames;
lib: RPCNode | Web3Node;
service: string;
estimateGas?: boolean;
hidden?: boolean;
}
declare enum StaticNodeName {
ETH_MEW = 'eth_mew',
ETH_MYCRYPTO = 'eth_mycrypto',
ETH_ETHSCAN = 'eth_ethscan',
ETH_INFURA = 'eth_infura',
ROP_MEW = 'rop_mew',
ROP_INFURA = 'rop_infura',
KOV_ETHSCAN = 'kov_ethscan',
RIN_ETHSCAN = 'rin_ethscan',
RIN_INFURA = 'rin_infura',
ETC_EPOOL = 'etc_epool',
UBQ = 'ubq',
EXP_TECH = 'exp_tech'
}
type NonWeb3NodeConfigs = { [key in StaticNodeName]: StaticNodeConfig };
interface Web3NodeConfig {
web3?: StaticNodeConfig;
}
type NodeConfig = StaticNodesState[StaticNodeName] | CustomNodesState[string];

View File

@ -1,9 +1,9 @@
import { NETWORKS, NetworkConfig } from 'config';
import { StaticNetworkConfig } from 'types/network';
describe('Networks', () => {
Object.keys(NETWORKS).forEach(networkId => {
it(`${networkId} contains non-null dPathFormats`, () => {
const network: NetworkConfig = NETWORKS[networkId];
const network: StaticNetworkConfig = NETWORKS[networkId];
Object.values(network.dPathFormats).forEach(dPathFormat => {
expect(dPathFormat).toBeTruthy();
});

View File

@ -1,4 +1,3 @@
import { NODES, NodeConfig } from 'config';
import { RPCNode } from '../../common/libs/nodes';
import { Validator } from 'jsonschema';
import { schema } from '../../common/libs/validators';
@ -6,6 +5,7 @@ import 'url-search-params-polyfill';
import EtherscanNode from 'libs/nodes/etherscan';
import InfuraNode from 'libs/nodes/infura';
import RpcNodeTestConfig from './RpcNodeTestConfig';
import { StaticNodeConfig } from 'types/node';
const v = new Validator();
@ -63,7 +63,7 @@ function testRpcRequests(node: RPCNode, service: string) {
});
}
const mapNodeEndpoints = (nodes: { [key: string]: NodeConfig }) => {
const mapNodeEndpoints = (nodes: { [key: string]: StaticNodeConfig }) => {
const { RpcNodes, EtherscanNodes, InfuraNodes } = RpcNodeTestConfig;
RpcNodes.forEach(n => {

View File

@ -4,7 +4,6 @@ import Adapter from 'enzyme-adapter-react-16';
import SendTransaction from 'containers/Tabs/SendTransaction';
import shallowWithStore from '../utils/shallowWithStore';
import { createMockStore } from 'redux-test-utils';
import { NODES } from 'config';
import { RouteComponentProps } from 'react-router';
import { createMockRouteComponentProps } from '../utils/mockRouteComponentProps';

View File

@ -1,6 +1,5 @@
import { config, INITIAL_STATE } from 'reducers/config';
import { config } from 'reducers/config';
import * as configActions from 'actions/config';
import { NODES, NETWORKS } from 'config';
import { makeCustomNodeId, makeNodeConfigFromCustomConfig } from 'utils/node';
const custNode = {

View File

@ -1,6 +1,6 @@
import { customTokens } from 'reducers/customTokens';
import { Token } from 'config';
import * as customTokensActions from 'actions/customTokens';
import { Token } from 'types/network';
describe('customTokens reducer', () => {
const token1: Token = {

View File

@ -12,7 +12,6 @@ import {
equivalentNodeOrDefault,
reload
} from 'sagas/config';
import { NODES, NodeConfig, NETWORKS } from 'config';
import {
getNodeName,
getNodeConfig,
@ -20,11 +19,12 @@ import {
getCustomNodeConfigs,
getCustomNetworkConfigs
} from 'selectors/config';
import { INITIAL_STATE as configInitialState } from 'reducers/config';
import { Web3Wallet } from 'libs/wallet';
import { RPCNode } from 'libs/nodes';
import { showNotification } from 'actions/notifications';
import { translateRaw } from 'translations';
import { StaticNodeConfig } from 'types/node';
// init module
configuredStore.getState();
@ -289,7 +289,7 @@ describe('unsetWeb3Node*', () => {
describe('unsetWeb3NodeOnWalletEvent*', () => {
const fakeAction = {};
const mockNode = 'web3';
const mockNodeConfig: Partial<NodeConfig> = { network: 'ETH' };
const mockNodeConfig: Partial<StaticNodeConfig> = { network: 'ETH' };
const gen = unsetWeb3NodeOnWalletEvent(fakeAction);
it('should select getNode', () => {

View File

@ -7,13 +7,13 @@ import { getDesiredToken, getWallets } from 'selectors/deterministicWallets';
import { getTokens } from 'selectors/wallet';
import { getNodeLib } from 'selectors/config';
import * as dWalletActions from 'actions/deterministicWallets';
import { Token } from 'config';
import {
getDeterministicWallets,
updateWalletValues,
updateWalletTokenValues
} from 'sagas/deterministicWallets';
import { TokenValue, Wei } from 'libs/units';
import { Token } from 'types/network';
// init module
configuredStore.getState();

View File

@ -14,7 +14,7 @@ import {
import { Wei } from 'libs/units';
import { changeNodeIntent, web3UnsetNode } from 'actions/config';
import { INode } from 'libs/nodes/INode';
import { initWeb3Node, Token, N_FACTOR } from 'config';
import { N_FACTOR } from 'config';
import { apply, call, fork, put, select, take, cancel } from 'redux-saga/effects';
import { getNodeLib, getOffline } from 'selectors/config';
import { getWalletInst, getWalletConfigTokens } from 'selectors/wallet';
@ -37,7 +37,7 @@ import { cloneableGenerator, createMockTask } from 'redux-saga/utils';
import { showNotification } from 'actions/notifications';
import translate from 'translations';
import { IFullWallet, fromV3 } from 'ethereumjs-wallet';
import { Token } from 'types/network';
// init module
configuredStore.getState();
const offline = false;

View File

@ -9,12 +9,10 @@
"allowJs": true,
"baseUrl": "./common/",
"paths": {
"shared*": ["../shared*"]
"shared*": ["../shared*"],
"types*": ["../shared/types*"]
},
"lib": [
"es2017",
"dom"
],
"lib": ["es2017", "dom"],
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"noEmitOnError": false,
@ -23,6 +21,7 @@
},
"include": [
"./common/",
"./shared/",
"./electron/",
"spec",
"./node_modules/types-rlp/index.d.ts"