Merge in typings
This commit is contained in:
parent
88532cdc3c
commit
bc10197ebf
|
@ -0,0 +1,19 @@
|
|||
import { ConfigAction } from './config';
|
||||
import { CustomTokenAction } from './customTokens';
|
||||
import { DeterministicWalletAction } from './deterministicWallets';
|
||||
import { EnsAction } from './ens';
|
||||
import { NotificationsAction } from './notifications';
|
||||
import { RatesAction } from './rates';
|
||||
import { SwapAction } from './swap';
|
||||
import { TransactionAction } from './transaction';
|
||||
import { WalletAction } from './wallet';
|
||||
export type AllActions =
|
||||
| ConfigAction
|
||||
| CustomTokenAction
|
||||
| DeterministicWalletAction
|
||||
| EnsAction
|
||||
| NotificationsAction
|
||||
| RatesAction
|
||||
| SwapAction
|
||||
| TransactionAction
|
||||
| WalletAction;
|
|
@ -5,7 +5,7 @@ import { State } from 'reducers/rates';
|
|||
import { rateSymbols, TFetchCCRates } from 'actions/rates';
|
||||
import { TokenBalance } from 'selectors/wallet';
|
||||
import { Balance } from 'libs/wallet';
|
||||
import { ETH_DECIMAL, convertTokenBase } from 'libs/units';
|
||||
import { ETH_DECIMAL, convertTokenBase, Wei, TokenValue } from 'libs/units';
|
||||
import Spinner from 'components/ui/Spinner';
|
||||
import UnitDisplay from 'components/ui/UnitDisplay';
|
||||
import './EquivalentValues.scss';
|
||||
|
@ -129,15 +129,19 @@ export default class EquivalentValues extends React.Component<Props, CmpState> {
|
|||
};
|
||||
|
||||
private makeBalanceLookup(props: Props) {
|
||||
interface IBalanceLookup {
|
||||
[unit: string]: Wei | TokenValue | undefined;
|
||||
}
|
||||
|
||||
const tokenBalances = props.tokenBalances || [];
|
||||
this.balanceLookup = tokenBalances.reduce(
|
||||
(prev, tk) => {
|
||||
(balanceLookup, currentToken) => {
|
||||
// Piggy-back off of this reduce to add to decimal lookup
|
||||
this.decimalLookup[tk.symbol] = tk.decimal;
|
||||
prev[tk.symbol] = tk.balance;
|
||||
return prev;
|
||||
this.decimalLookup[currentToken.symbol] = currentToken.decimal;
|
||||
balanceLookup[currentToken.symbol] = currentToken.balance;
|
||||
return balanceLookup;
|
||||
},
|
||||
{ ETH: props.balance && props.balance.wei }
|
||||
{ ETH: props.balance && props.balance.wei } as IBalanceLookup
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -168,18 +172,26 @@ export default class EquivalentValues extends React.Component<Props, CmpState> {
|
|||
): {
|
||||
[key: string]: BN | undefined;
|
||||
} {
|
||||
interface IEquivalentValues {
|
||||
[unit: string]: Wei | TokenValue;
|
||||
}
|
||||
// Recursively call on all currencies
|
||||
if (currency === ALL_OPTION) {
|
||||
return ['ETH'].concat(this.requestedCurrencies || []).reduce(
|
||||
(prev, curr) => {
|
||||
const currValues = this.getEquivalentValues(curr);
|
||||
rateSymbols.forEach(sym => (prev[sym] = prev[sym].add(currValues[sym] || new BN(0))));
|
||||
rateSymbols.forEach(
|
||||
sym => (prev[sym] = prev[sym].add(currValues[sym] || TokenValue('0')))
|
||||
);
|
||||
return prev;
|
||||
},
|
||||
rateSymbols.reduce((prev, sym) => {
|
||||
prev[sym] = new BN(0);
|
||||
return prev;
|
||||
}, {})
|
||||
rateSymbols.reduce(
|
||||
(prev, sym) => {
|
||||
prev[sym] = new BN(0);
|
||||
return prev;
|
||||
},
|
||||
{} as IEquivalentValues
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -195,9 +207,12 @@ export default class EquivalentValues extends React.Component<Props, CmpState> {
|
|||
this.decimalLookup[currency] === undefined ? ETH_DECIMAL : this.decimalLookup[currency];
|
||||
const adjustedBalance = convertTokenBase(balance, decimal, ETH_DECIMAL);
|
||||
|
||||
return rateSymbols.reduce((prev, sym) => {
|
||||
prev[sym] = adjustedBalance.muln(rates[currency][sym]);
|
||||
return prev;
|
||||
}, {});
|
||||
return rateSymbols.reduce(
|
||||
(prev, sym) => {
|
||||
prev[sym] = adjustedBalance.muln(rates[currency][sym]);
|
||||
return prev;
|
||||
},
|
||||
{} as IEquivalentValues
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ interface State {
|
|||
showCustomTokenForm: boolean;
|
||||
}
|
||||
export default class TokenBalances extends React.Component<Props, State> {
|
||||
public state = {
|
||||
public state: State = {
|
||||
trackedTokens: {},
|
||||
showCustomTokenForm: false
|
||||
};
|
||||
|
|
|
@ -10,7 +10,7 @@ interface StateProps {
|
|||
}
|
||||
|
||||
interface OwnProps {
|
||||
withProps(props: CallBackProps);
|
||||
withProps(props: CallBackProps): React.ReactElement<any> | null;
|
||||
onChange(value: React.FormEvent<HTMLInputElement>): void;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ export default class GenerateKeystoreModal extends React.Component<Props, State>
|
|||
}
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps) {
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
if (nextProps.privateKey !== this.props.privateKey) {
|
||||
this.setState({ privateKey: nextProps.privateKey });
|
||||
this.setState({ privateKey: nextProps.privateKey || '' });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ const NETWORK_KEYS = Object.keys(NETWORKS);
|
|||
const CUSTOM = 'custom';
|
||||
|
||||
interface Input {
|
||||
name: string;
|
||||
name: keyof State;
|
||||
placeholder?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ export default class CustomNodeModal extends React.Component<Props, State> {
|
|||
<input
|
||||
className={classnames({
|
||||
'form-control': true,
|
||||
'is-invalid': this.state[input.name] && invalids[input.name]
|
||||
'is-invalid': !!(this.state[input.name] && invalids[input.name])
|
||||
})}
|
||||
value={this.state[input.name]}
|
||||
onChange={this.handleChange}
|
||||
|
|
|
@ -65,7 +65,7 @@ class DeterministicWalletsModalClass extends React.Component<Props, State> {
|
|||
this.getAddresses();
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps) {
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
const { publicKey, chainCode, seed, dPath } = this.props;
|
||||
if (
|
||||
nextProps.publicKey !== publicKey ||
|
||||
|
@ -235,7 +235,7 @@ class DeterministicWalletsModalClass extends React.Component<Props, State> {
|
|||
}
|
||||
};
|
||||
|
||||
private selectAddress(selectedAddress, selectedAddrIndex) {
|
||||
private selectAddress(selectedAddress: string, selectedAddrIndex: number) {
|
||||
this.setState({ selectedAddress, selectedAddrIndex });
|
||||
}
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ export class MnemonicDecrypt extends Component<Props, State> {
|
|||
this.setState({ dPath });
|
||||
};
|
||||
|
||||
private handleUnlock = (address, index) => {
|
||||
private handleUnlock = (address: string, index: number) => {
|
||||
const { formattedPhrase, pass, dPath } = this.state;
|
||||
|
||||
this.props.onUnlock({
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import Modal, { IButton } from 'components/ui/Modal';
|
||||
import { UnregisterCallback } from 'history';
|
||||
|
||||
interface Props extends RouteComponentProps<{}> {
|
||||
when: boolean;
|
||||
|
@ -14,9 +15,9 @@ interface State {
|
|||
}
|
||||
|
||||
class NavigationPromptClass extends React.Component<Props, State> {
|
||||
public unblock;
|
||||
public unblock: UnregisterCallback;
|
||||
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
nextLocation: null,
|
||||
|
|
|
@ -19,7 +19,7 @@ interface State {
|
|||
}
|
||||
|
||||
class InteractForm extends Component<Props, State> {
|
||||
public state = {
|
||||
public state: State = {
|
||||
address: '',
|
||||
abiJson: ''
|
||||
};
|
||||
|
@ -35,7 +35,11 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
|
|||
const validEthAddress = isValidETHAddress(address);
|
||||
const validAbiJson = isValidAbiJson(abiJson);
|
||||
const showContractAccessButton = validEthAddress && validAbiJson;
|
||||
let contractOptions;
|
||||
interface IContractOpts {
|
||||
name: string;
|
||||
value: string | null;
|
||||
}
|
||||
let contractOptions: IContractOpts[];
|
||||
if (contracts && contracts.length) {
|
||||
contractOptions = [
|
||||
{
|
||||
|
@ -86,8 +90,8 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
|
|||
onChange={this.handleSelectContract}
|
||||
disabled={!contracts || !contracts.length}
|
||||
>
|
||||
{contractOptions.map(opt => (
|
||||
<option key={opt.value} value={opt.value}>
|
||||
{contractOptions.map((opt, idx) => (
|
||||
<option key={opt.value || idx} value={opt.value || undefined}>
|
||||
{opt.name}
|
||||
</option>
|
||||
))}
|
||||
|
@ -122,9 +126,12 @@ e":"a", "type":"uint256"}], "name":"foo", "outputs": [] }]';
|
|||
);
|
||||
}
|
||||
|
||||
private handleInput = name => (ev: any) => {
|
||||
private handleInput = (name: keyof State) => (
|
||||
ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>
|
||||
) => {
|
||||
this.props.resetState();
|
||||
this.setState({ [name]: ev.target.value });
|
||||
|
||||
this.setState({ [name as any]: ev.currentTarget.value });
|
||||
};
|
||||
|
||||
private handleSelectContract = (ev: any) => {
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
SendRawTxRequest,
|
||||
GetCurrentBlockRequest
|
||||
} from './types';
|
||||
import { IHexStrWeb3Transaction, IHexStrTransaction } from 'libs/transaction';
|
||||
|
||||
export default class EtherscanRequests extends RPCRequests {
|
||||
public sendRawTx(signedTx: string): SendRawTxRequest {
|
||||
|
@ -20,7 +21,7 @@ export default class EtherscanRequests extends RPCRequests {
|
|||
};
|
||||
}
|
||||
|
||||
public estimateGas(transaction): EstimateGasRequest {
|
||||
public estimateGas(transaction: IHexStrWeb3Transaction): EstimateGasRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
action: 'eth_estimateGas',
|
||||
|
@ -40,7 +41,7 @@ export default class EtherscanRequests extends RPCRequests {
|
|||
};
|
||||
}
|
||||
|
||||
public ethCall(transaction): CallRequest {
|
||||
public ethCall(transaction: Pick<IHexStrTransaction, 'to' | 'data'>): CallRequest {
|
||||
return {
|
||||
module: 'proxy',
|
||||
action: 'eth_call',
|
||||
|
|
|
@ -41,10 +41,10 @@ export default class RPCClient {
|
|||
}).then(r => r.json());
|
||||
};
|
||||
|
||||
private createHeaders = headerObject => {
|
||||
private createHeaders = (headerObject: HeadersInit) => {
|
||||
const headers = new Headers();
|
||||
Object.keys(headerObject).forEach(name => {
|
||||
headers.append(name, headerObject[name]);
|
||||
Object.entries(headerObject).forEach(([name, value]) => {
|
||||
headers.append(name, value);
|
||||
});
|
||||
return headers;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ export interface GetAccountsRequest extends RPCRequestBase {
|
|||
method: 'eth_accounts';
|
||||
}
|
||||
|
||||
type TWeb3ProviderCallback = (error, result: JsonRpcResponse | JsonRpcResponse[]) => any;
|
||||
type TWeb3ProviderCallback = (error: string, result: JsonRpcResponse | JsonRpcResponse[]) => any;
|
||||
type TSendAsync = (request: RPCRequest | any, callback: TWeb3ProviderCallback) => void;
|
||||
|
||||
export interface IWeb3Provider {
|
||||
|
|
|
@ -10,9 +10,9 @@ export interface ITransaction {
|
|||
gasPrice: Wei;
|
||||
nonce: BN;
|
||||
chainId: number;
|
||||
v;
|
||||
r;
|
||||
s;
|
||||
v: Buffer;
|
||||
r: Buffer;
|
||||
s: Buffer;
|
||||
}
|
||||
|
||||
export interface IHexStrTransaction {
|
||||
|
|
|
@ -162,7 +162,21 @@ export const isValidNonce = (value: string): boolean => {
|
|||
return valid;
|
||||
};
|
||||
|
||||
function isValidResult(response: JsonRpcResponse, schemaFormat): boolean {
|
||||
enum API_NAME {
|
||||
Get_Balance = 'Get Balance',
|
||||
Estimate_Gas = 'Estimate Gas',
|
||||
Call_Request = 'Call Request',
|
||||
Token_Balance = 'Token Balance',
|
||||
Transaction_Count = 'Transaction Count',
|
||||
Current_Block = 'Current Block',
|
||||
Raw_Tx = 'Raw Tx',
|
||||
Send_Transaction = 'Send Transaction',
|
||||
Sign_Message = 'Sign Message',
|
||||
Get_Accounts = 'Get Accounts',
|
||||
Net_Version = 'Net Version'
|
||||
}
|
||||
|
||||
function isValidResult(response: JsonRpcResponse, schemaFormat: typeof schema.RpcNode): boolean {
|
||||
return v.validate(response, schemaFormat).valid;
|
||||
}
|
||||
|
||||
|
@ -174,8 +188,8 @@ function formatErrors(response: JsonRpcResponse, apiType: string) {
|
|||
}
|
||||
|
||||
const isValidEthCall = (response: JsonRpcResponse, schemaType: typeof schema.RpcNode) => (
|
||||
apiName,
|
||||
cb?
|
||||
apiName: API_NAME,
|
||||
cb?: () => any
|
||||
) => {
|
||||
if (!isValidResult(response, schemaType)) {
|
||||
if (cb) {
|
||||
|
@ -187,36 +201,36 @@ const isValidEthCall = (response: JsonRpcResponse, schemaType: typeof schema.Rpc
|
|||
};
|
||||
|
||||
export const isValidGetBalance = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Get Balance');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Get_Balance);
|
||||
|
||||
export const isValidEstimateGas = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Estimate Gas');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Estimate_Gas);
|
||||
|
||||
export const isValidCallRequest = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Call Request');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Call_Request);
|
||||
|
||||
export const isValidTokenBalance = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Token Balance', () => ({
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Token_Balance, () => ({
|
||||
result: 'Failed'
|
||||
}));
|
||||
|
||||
export const isValidTransactionCount = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Transaction Count');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Transaction_Count);
|
||||
|
||||
export const isValidCurrentBlock = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Current Block');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Current_Block);
|
||||
|
||||
export const isValidRawTxApi = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Raw Tx');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Raw_Tx);
|
||||
|
||||
export const isValidSendTransaction = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Send Transaction');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Send_Transaction);
|
||||
|
||||
export const isValidSignMessage = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Sign Message');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Sign_Message);
|
||||
|
||||
export const isValidGetAccounts = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Get Accounts');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Get_Accounts);
|
||||
|
||||
export const isValidGetNetVersion = (response: JsonRpcResponse) =>
|
||||
isValidEthCall(response, schema.RpcNode)('Net Version');
|
||||
isValidEthCall(response, schema.RpcNode)(API_NAME.Net_Version);
|
||||
|
|
|
@ -25,7 +25,7 @@ export interface AppState {
|
|||
transaction: TransactionState;
|
||||
}
|
||||
|
||||
export default combineReducers({
|
||||
export default combineReducers<AppState>({
|
||||
config,
|
||||
swap,
|
||||
notifications,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { State, RequestStatus } from './typings';
|
||||
import { TypeKeys as TK, ResetAction, NetworkAction } from 'actions/transaction';
|
||||
import { Action } from 'redux';
|
||||
|
||||
const INITIAL_STATE: State = {
|
||||
gasEstimationStatus: null,
|
||||
|
@ -13,9 +12,9 @@ const getPostFix = (str: string) => {
|
|||
return arr[arr.length - 1];
|
||||
};
|
||||
|
||||
const nextState = (field: keyof State) => (state: State, action: Action): State => ({
|
||||
const nextState = (field: keyof State) => (state: State, action: NetworkAction): State => ({
|
||||
...state,
|
||||
[field]: RequestStatus[getPostFix(action.type)]
|
||||
[field]: RequestStatus[getPostFix(action.type) as keyof typeof RequestStatus]
|
||||
});
|
||||
|
||||
const reset = () => INITIAL_STATE;
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
select,
|
||||
race
|
||||
} from 'redux-saga/effects';
|
||||
import { NODES, NodeConfig } from 'config/data';
|
||||
import { NODES, NodeConfig, CustomNodeConfig, CustomNetworkConfig } from 'config/data';
|
||||
import {
|
||||
makeCustomNodeId,
|
||||
getCustomNodeConfigFromId,
|
||||
|
@ -42,6 +42,7 @@ import { Web3Wallet } from 'libs/wallet';
|
|||
import { getWalletInst } from 'selectors/wallet';
|
||||
import { TypeKeys as WalletTypeKeys } from 'actions/wallet/constants';
|
||||
import { State as ConfigState, INITIAL_STATE as configInitialState } from 'reducers/config';
|
||||
import { SetWalletAction } from 'actions/wallet';
|
||||
|
||||
export const getConfig = (state: AppState): ConfigState => state.config;
|
||||
|
||||
|
@ -178,14 +179,20 @@ export function* switchToNewNode(action: AddCustomNodeAction): SagaIterator {
|
|||
yield put(changeNodeIntent(nodeId));
|
||||
}
|
||||
|
||||
interface INetworksInUse {
|
||||
[networkName: string]: boolean;
|
||||
}
|
||||
// If there are any orphaned custom networks, purge them
|
||||
export function* cleanCustomNetworks(): SagaIterator {
|
||||
const customNodes = yield select(getCustomNodeConfigs);
|
||||
const customNetworks = yield select(getCustomNetworkConfigs);
|
||||
const networksInUse = customNodes.reduce((prev, conf) => {
|
||||
prev[conf.network] = true;
|
||||
return prev;
|
||||
}, {});
|
||||
const customNodes: CustomNodeConfig[] = yield select(getCustomNodeConfigs);
|
||||
const customNetworks: CustomNetworkConfig[] = yield select(getCustomNetworkConfigs);
|
||||
const networksInUse = customNodes.reduce(
|
||||
(prev, conf) => {
|
||||
prev[conf.network] = true;
|
||||
return prev;
|
||||
},
|
||||
{} as INetworksInUse
|
||||
);
|
||||
|
||||
for (const net of customNetworks) {
|
||||
if (!networksInUse[makeCustomNetworkId(net)]) {
|
||||
|
@ -195,7 +202,7 @@ export function* cleanCustomNetworks(): SagaIterator {
|
|||
}
|
||||
|
||||
// unset web3 as the selected node if a non-web3 wallet has been selected
|
||||
export function* unsetWeb3NodeOnWalletEvent(action): SagaIterator {
|
||||
export function* unsetWeb3NodeOnWalletEvent(action: SetWalletAction): SagaIterator {
|
||||
const node = yield select(getNode);
|
||||
const nodeConfig = yield select(getNodeConfig);
|
||||
const newWallet = action.payload;
|
||||
|
|
|
@ -13,10 +13,16 @@ export function* getTokenBalances(wallet: IWallet, tokens: Token[]) {
|
|||
const node: INode = yield select(getNodeLib);
|
||||
const address: string = yield apply(wallet, wallet.getAddressString);
|
||||
const tokenBalances: TokenBalance[] = yield apply(node, node.getTokenBalances, [address, tokens]);
|
||||
return tokens.reduce((acc, t, i) => {
|
||||
acc[t.symbol] = tokenBalances[i];
|
||||
return acc;
|
||||
}, {});
|
||||
interface ITokenbalances {
|
||||
[tokenSymbol: string]: TokenBalance;
|
||||
}
|
||||
return tokens.reduce(
|
||||
(acc, currentToken, i) => {
|
||||
acc[currentToken.symbol] = tokenBalances[i];
|
||||
return acc;
|
||||
},
|
||||
{} as ITokenbalances
|
||||
);
|
||||
}
|
||||
|
||||
// Return an array of the tokens that meet any of the following conditions:
|
||||
|
|
|
@ -45,6 +45,7 @@ import translate from 'translations';
|
|||
import Web3Node, { isWeb3Node } from 'libs/nodes/web3';
|
||||
import { loadWalletConfig, saveWalletConfig } from 'utils/localStorage';
|
||||
import { getTokenBalances, filterScannedTokenBalances } from './helpers';
|
||||
import { AllActions } from 'actions';
|
||||
|
||||
export interface TokenBalanceLookup {
|
||||
[symbol: string]: TokenBalance;
|
||||
|
@ -205,7 +206,7 @@ export function* unlockWeb3(): SagaIterator {
|
|||
yield call(initWeb3Node);
|
||||
yield put(changeNodeIntent('web3'));
|
||||
yield take(
|
||||
action =>
|
||||
(action: AllActions) =>
|
||||
action.type === ConfigTypeKeys.CONFIG_NODE_CHANGE && action.payload.nodeSelection === 'web3'
|
||||
);
|
||||
|
||||
|
|
|
@ -80,7 +80,10 @@ const serializedAndTransactionFieldsMatch = (state: AppState, isLocallySigned: b
|
|||
|
||||
const t2 = getTransactionFields(makeTransaction(serialzedTransaction));
|
||||
const checkValidity = (tx: IHexStrTransaction) =>
|
||||
Object.keys(tx).reduce((match, currField) => match && t1[currField] === t2[currField], true);
|
||||
Object.keys(tx).reduce(
|
||||
(match, currField: keyof IHexStrTransaction) => match && t1[currField] === t2[currField],
|
||||
true
|
||||
);
|
||||
//reduce both ways to make sure both are exact same
|
||||
const transactionsMatch = checkValidity(t1) && checkValidity(t2);
|
||||
// if its signed then verify the signature too
|
||||
|
|
|
@ -10,12 +10,12 @@ import {
|
|||
State as TransactionState
|
||||
} from 'reducers/transaction';
|
||||
import { State as SwapState, INITIAL_STATE as swapInitialState } from 'reducers/swap';
|
||||
import { applyMiddleware, createStore } from 'redux';
|
||||
import { applyMiddleware, createStore, Store } from 'redux';
|
||||
import { composeWithDevTools } from 'redux-devtools-extension';
|
||||
import { createLogger } from 'redux-logger';
|
||||
import createSagaMiddleware from 'redux-saga';
|
||||
import { loadStatePropertyOrEmptyObject, saveState } from 'utils/localStorage';
|
||||
import RootReducer from './reducers';
|
||||
import RootReducer, { AppState } from './reducers';
|
||||
import promiseMiddleware from 'redux-promise-middleware';
|
||||
import { getNodeConfigFromId } from 'utils/node';
|
||||
import sagas from './sagas';
|
||||
|
@ -30,7 +30,7 @@ const configureStore = () => {
|
|||
promiseTypeSuffixes: ['REQUESTED', 'SUCCEEDED', 'FAILED']
|
||||
});
|
||||
let middleware;
|
||||
let store;
|
||||
let store: Store<AppState>;
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
middleware = composeWithDevTools(
|
||||
|
@ -106,11 +106,11 @@ const configureStore = () => {
|
|||
persistedInitialState.config.nodeSelection = configInitialState.nodeSelection;
|
||||
}
|
||||
|
||||
store = createStore(RootReducer, persistedInitialState, middleware);
|
||||
store = createStore<AppState>(RootReducer, persistedInitialState as AppState, middleware);
|
||||
|
||||
// Add all of the sagas to the middleware
|
||||
Object.keys(sagas).forEach(saga => {
|
||||
sagaMiddleware.run(sagas[saga]);
|
||||
Object.values(sagas).forEach(saga => {
|
||||
sagaMiddleware.run(saga);
|
||||
});
|
||||
|
||||
store.subscribe(
|
||||
|
|
|
@ -3,9 +3,19 @@ import React from 'react';
|
|||
import { getLanguageSelection } from 'selectors/config';
|
||||
import { configuredStore } from '../store';
|
||||
const fallbackLanguage = 'en';
|
||||
const repository = {};
|
||||
const repository: {
|
||||
[language: string]: {
|
||||
[translationName: string]: string;
|
||||
};
|
||||
} = {};
|
||||
|
||||
const languages = [
|
||||
interface ILanguage {
|
||||
code: string;
|
||||
data: {
|
||||
[translationName: string]: string;
|
||||
};
|
||||
}
|
||||
const languages: ILanguage[] = [
|
||||
require('./lang/de.json'),
|
||||
require('./lang/el.json'),
|
||||
require('./lang/en.json'),
|
||||
|
|
|
@ -92,7 +92,7 @@ declare module 'ethereumjs-tx' {
|
|||
* sign a transaction with a given a private key
|
||||
* @param {Buffer} privateKey
|
||||
*/
|
||||
public sign(privateKey: Buffer);
|
||||
public sign(privateKey: Buffer): void;
|
||||
|
||||
/**
|
||||
* The amount of gas paid for the data in this tx
|
||||
|
|
|
@ -2,6 +2,7 @@ export const REDUX_STATE = 'REDUX_STATE';
|
|||
import { State as SwapState } from 'reducers/swap';
|
||||
import { IWallet, WalletConfig } from 'libs/wallet';
|
||||
import { sha256 } from 'ethereumjs-util';
|
||||
import { AppState } from 'reducers';
|
||||
|
||||
export function loadState<T>(): T | undefined {
|
||||
try {
|
||||
|
@ -26,8 +27,8 @@ export const saveState = (state: any) => {
|
|||
|
||||
export type SwapLocalStorage = SwapState;
|
||||
|
||||
export function loadStatePropertyOrEmptyObject<T>(key: string): T | undefined {
|
||||
const localStorageState = loadState();
|
||||
export function loadStatePropertyOrEmptyObject<T>(key: keyof AppState): T | undefined {
|
||||
const localStorageState: Partial<AppState> | undefined = loadState();
|
||||
if (localStorageState) {
|
||||
if (localStorageState.hasOwnProperty(key)) {
|
||||
return localStorageState[key] as T;
|
||||
|
|
|
@ -18,8 +18,8 @@ export default function(element: React.ReactElement<any>, opts: PrintOptions = {
|
|||
// Convert popupFeatures into a key=value,key=value string. See
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/open#Window_features
|
||||
// for more information.
|
||||
const featuresStr = Object.keys(options.popupFeatures)
|
||||
.map(key => `${key}=${options.popupFeatures[key]}`)
|
||||
const featuresStr = Object.entries(options.popupFeatures)
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join(',');
|
||||
|
||||
const popup = window.open('about:blank', 'printWindow', featuresStr);
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"moduleResolution": "node",
|
||||
"noEmitOnError": false,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitAny": true
|
||||
},
|
||||
"include": [
|
||||
"./common/",
|
||||
|
@ -26,4 +27,4 @@
|
|||
"awesomeTypescriptLoaderOptions": {
|
||||
"transpileOnly": true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue