1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-12-29 02:18:06 +00:00

refactor Coin > Network

This commit is contained in:
Szymon Lesisz 2018-10-15 15:44:10 +02:00
parent 5d9db80d51
commit ed7501c4fc
25 changed files with 111 additions and 179 deletions

View File

@ -1,9 +1,9 @@
{ {
"coins": [ "networks": [
{ {
"name": "Ethereum", "name": "Ethereum",
"symbol": "ETH", "symbol": "ETH",
"network": "eth", "shortcut": "eth",
"bip44": "m/44'/60'/0'/0", "bip44": "m/44'/60'/0'/0",
"chainId": 1, "chainId": 1,
"defaultGasPrice": 64, "defaultGasPrice": 64,
@ -21,7 +21,7 @@
{ {
"name": "Ethereum Classic", "name": "Ethereum Classic",
"symbol": "ETC", "symbol": "ETC",
"network": "etc", "shortcut": "etc",
"chainId": 61, "chainId": 61,
"bip44": "m/44'/61'/0'/0", "bip44": "m/44'/61'/0'/0",
"defaultGasPrice": 64, "defaultGasPrice": 64,
@ -39,7 +39,7 @@
{ {
"name": "Ethereum Ropsten", "name": "Ethereum Ropsten",
"symbol": "tROP", "symbol": "tROP",
"network": "trop", "shortcut": "trop",
"chainId": 3, "chainId": 3,
"bip44": "m/44'/60'/0'/0", "bip44": "m/44'/60'/0'/0",
"defaultGasPrice": 64, "defaultGasPrice": 64,

View File

@ -16,5 +16,11 @@
"name": "Trezor13", "name": "Trezor13",
"symbol": "T013", "symbol": "T013",
"decimals": 13 "decimals": 13
},
{
"address": "0x58cda554935e4a1f2acbe15f8757400af275e084",
"name": "LahodCoin",
"symbol": "LAHOD",
"decimals": 13
} }
] ]

View File

@ -92,7 +92,7 @@ const start = (device: TrezorDevice, network: string, ignoreCompleted?: boolean)
return; return;
} }
const blockchain = getState().blockchain.find(b => b.name === network); const blockchain = getState().blockchain.find(b => b.shortcut === network);
if (blockchain && !blockchain.connected && (!discoveryProcess || !discoveryProcess.completed)) { if (blockchain && !blockchain.connected && (!discoveryProcess || !discoveryProcess.completed)) {
dispatch({ dispatch({
type: DISCOVERY.WAITING_FOR_BLOCKCHAIN, type: DISCOVERY.WAITING_FOR_BLOCKCHAIN,
@ -124,8 +124,8 @@ const start = (device: TrezorDevice, network: string, ignoreCompleted?: boolean)
// start discovery process // start discovery process
const begin = (device: TrezorDevice, network: string): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise<void> => { const begin = (device: TrezorDevice, network: string): AsyncAction => async (dispatch: Dispatch, getState: GetState): Promise<void> => {
const { config } = getState().localStorage; const { config } = getState().localStorage;
const coinToDiscover = config.coins.find(c => c.network === network); const networkData = config.networks.find(c => c.shortcut === network);
if (!coinToDiscover) return; if (!networkData) return;
dispatch({ dispatch({
type: DISCOVERY.WAITING_FOR_DEVICE, type: DISCOVERY.WAITING_FOR_DEVICE,
@ -140,7 +140,7 @@ const begin = (device: TrezorDevice, network: string): AsyncAction => async (dis
instance: device.instance, instance: device.instance,
state: device.state, state: device.state,
}, },
path: coinToDiscover.bip44, path: networkData.bip44,
keepSession: true, // acquire and hold session keepSession: true, // acquire and hold session
//useEmptyPassphrase: !device.instance, //useEmptyPassphrase: !device.instance,
useEmptyPassphrase: device.useEmptyPassphrase, useEmptyPassphrase: device.useEmptyPassphrase,
@ -179,7 +179,7 @@ const begin = (device: TrezorDevice, network: string): AsyncAction => async (dis
// send data to reducer // send data to reducer
dispatch({ dispatch({
type: DISCOVERY.START, type: DISCOVERY.START,
network: coinToDiscover.network, network,
device, device,
publicKey: response.payload.publicKey, publicKey: response.payload.publicKey,
chainCode: response.payload.chainCode, chainCode: response.payload.chainCode,

View File

@ -13,7 +13,7 @@ import * as buildUtils from 'utils/build';
import type { import type {
ThunkAction, AsyncAction, /* GetState, */ Dispatch, ThunkAction, AsyncAction, /* GetState, */ Dispatch,
} from 'flowtype'; } from 'flowtype';
import type { Config, Coin, TokensCollection } from 'reducers/LocalStorageReducer'; import type { Config, Network, TokensCollection } from 'reducers/LocalStorageReducer';
import Erc20AbiJSON from 'public/data/ERC20Abi.json'; import Erc20AbiJSON from 'public/data/ERC20Abi.json';
import AppConfigJSON from 'public/data/appConfig.json'; import AppConfigJSON from 'public/data/appConfig.json';
@ -99,8 +99,8 @@ export function loadTokensFromJSON(): AsyncAction {
const config: Config = await httpRequest(AppConfigJSON, 'json'); const config: Config = await httpRequest(AppConfigJSON, 'json');
if (!buildUtils.isDev()) { if (!buildUtils.isDev()) {
const index = config.coins.findIndex(c => c.network === 'trop'); const index = config.networks.findIndex(c => c.shortcut === 'trop');
delete config.coins[index]; delete config.networks[index];
} }
const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json'); const ERC20Abi = await httpRequest(Erc20AbiJSON, 'json');
@ -117,10 +117,10 @@ export function loadTokensFromJSON(): AsyncAction {
} }
// load tokens // load tokens
const tokens = await config.coins.reduce(async (promise: Promise<TokensCollection>, coin: Coin): Promise<TokensCollection> => { const tokens = await config.networks.reduce(async (promise: Promise<TokensCollection>, network: Network): Promise<TokensCollection> => {
const collection: TokensCollection = await promise; const collection: TokensCollection = await promise;
const json = await httpRequest(coin.tokens, 'json'); const json = await httpRequest(network.tokens, 'json');
collection[coin.network] = json; collection[network.shortcut] = json;
return collection; return collection;
}, Promise.resolve({})); }, Promise.resolve({}));
@ -195,41 +195,6 @@ export const loadData = (): ThunkAction => (dispatch: Dispatch): void => {
dispatch(loadTokensFromJSON()); dispatch(loadTokensFromJSON());
}; };
// const parseConfig = (json: JSON): Config => {
// if (json['coins']) {
// }
// for (let key in json) {
// if (key === 'coins') {
// }
// }
// const coins: Array<Object> = json.coins || [];
// if ("coins" in json){
// json.coins
// }
// if (!json.hasOwnProperty("fiatValueTickers")) throw new Error(`Property "fiatValueTickers" is missing in appConfig.json`);
// if (json.config && json.hasOwnProperty('coins') && Array.isArray(json.coins)) {
// json.coins.map(c => {
// return {
// }
// })
// } else {
// throw new Error(`Property "coins" is missing in appConfig.json`);
// }
// return {
// coins: [],
// fiatValueTickers: []
// }
// }
export const save = (key: string, value: string): ThunkAction => (): void => { export const save = (key: string, value: string): ThunkAction => (): void => {
if (typeof window.localStorage !== 'undefined') { if (typeof window.localStorage !== 'undefined') {
try { try {

View File

@ -71,8 +71,8 @@ export const paramsValidation = (params: RouterLocationState): PayloadAction<boo
// validate requested network // validate requested network
if (params.hasOwnProperty('network')) { if (params.hasOwnProperty('network')) {
const { config } = getState().localStorage; const { config } = getState().localStorage;
const coin = config.coins.find(c => c.network === params.network); const network = config.networks.find(c => c.shortcut === params.network);
if (!coin) return false; if (!network) return false;
if (!params.account) return false; if (!params.account) return false;
} }

View File

@ -63,7 +63,7 @@ const getAccountStatus = (state: State, selectedAccount: SelectedAccountState):
}; };
} }
const blockchain = state.blockchain.find(b => b.name === network.network); const blockchain = state.blockchain.find(b => b.shortcut === network.shortcut);
if (blockchain && !blockchain.connected) { if (blockchain && !blockchain.connected) {
return { return {
type: 'backend', type: 'backend',

View File

@ -130,7 +130,7 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS
return; return;
} }
const gasPrice: BigNumber = await dispatch(BlockchainActions.getGasPrice(network.network, network.defaultGasPrice)); const gasPrice: BigNumber = await dispatch(BlockchainActions.getGasPrice(network.shortcut, network.defaultGasPrice));
const gasLimit = network.defaultGasLimit.toString(); const gasLimit = network.defaultGasLimit.toString();
const feeLevels = ValidationActions.getFeeLevels(network.symbol, gasPrice, gasLimit); const feeLevels = ValidationActions.getFeeLevels(network.symbol, gasPrice, gasLimit);
const selectedFeeLevel = ValidationActions.getSelectedFeeLevel(feeLevels, initialState.selectedFeeLevel); const selectedFeeLevel = ValidationActions.getSelectedFeeLevel(feeLevels, initialState.selectedFeeLevel);
@ -139,7 +139,7 @@ export const init = (): AsyncAction => async (dispatch: Dispatch, getState: GetS
type: SEND.INIT, type: SEND.INIT,
state: { state: {
...initialState, ...initialState,
networkName: network.network, networkName: network.shortcut,
networkSymbol: network.symbol, networkSymbol: network.symbol,
currency: network.symbol, currency: network.symbol,
feeLevels, feeLevels,
@ -411,7 +411,7 @@ const estimateGasPrice = (): AsyncAction => async (dispatch: Dispatch, getState:
return; return;
} }
const gasLimit = await dispatch(BlockchainActions.estimateGasLimit(network.network, state.data, state.amount, state.gasPrice)); const gasLimit = await dispatch(BlockchainActions.estimateGasLimit(network.shortcut, state.data, state.amount, state.gasPrice));
// double check "data" field // double check "data" field
// possible race condition when data changed before backend respond // possible race condition when data changed before backend respond
@ -439,7 +439,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge
const nonce = pendingNonce > 0 && pendingNonce >= account.nonce ? pendingNonce : account.nonce; const nonce = pendingNonce > 0 && pendingNonce >= account.nonce ? pendingNonce : account.nonce;
const txData = await dispatch(prepareEthereumTx({ const txData = await dispatch(prepareEthereumTx({
network: network.network, network: network.shortcut,
token: isToken ? findToken(getState().tokens, account.address, currentState.currency, account.deviceState) : null, token: isToken ? findToken(getState().tokens, account.address, currentState.currency, account.deviceState) : null,
from: account.address, from: account.address,
to: currentState.address, to: currentState.address,
@ -487,7 +487,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge
const serializedTx: string = await dispatch(serializeEthereumTx(txData)); const serializedTx: string = await dispatch(serializeEthereumTx(txData));
const push = await TrezorConnect.pushTransaction({ const push = await TrezorConnect.pushTransaction({
tx: serializedTx, tx: serializedTx,
coin: network.network, coin: network.shortcut,
}); });
if (!push.success) { if (!push.success) {

View File

@ -174,7 +174,7 @@ export const addressLabel = ($state: State): PayloadAction<State> => (dispatch:
const savedAccounts = getState().accounts.filter(a => a.address.toLowerCase() === address.toLowerCase()); const savedAccounts = getState().accounts.filter(a => a.address.toLowerCase() === address.toLowerCase());
if (savedAccounts.length > 0) { if (savedAccounts.length > 0) {
// check if found account belongs to this network // check if found account belongs to this network
const currentNetworkAccount = savedAccounts.find(a => a.network === network.network); const currentNetworkAccount = savedAccounts.find(a => a.network === network.shortcut);
if (currentNetworkAccount) { if (currentNetworkAccount) {
const device = findDevice(getState().devices, currentNetworkAccount.deviceID, currentNetworkAccount.deviceState); const device = findDevice(getState().devices, currentNetworkAccount.deviceID, currentNetworkAccount.deviceState);
if (device) { if (device) {
@ -184,8 +184,8 @@ export const addressLabel = ($state: State): PayloadAction<State> => (dispatch:
// corner-case: the same derivation path is used on different networks // corner-case: the same derivation path is used on different networks
const otherNetworkAccount = savedAccounts[0]; const otherNetworkAccount = savedAccounts[0];
const device = findDevice(getState().devices, otherNetworkAccount.deviceID, otherNetworkAccount.deviceState); const device = findDevice(getState().devices, otherNetworkAccount.deviceID, otherNetworkAccount.deviceState);
const { coins } = getState().localStorage.config; const { networks } = getState().localStorage.config;
const otherNetwork = coins.find(c => c.network === otherNetworkAccount.network); const otherNetwork = networks.find(c => c.shortcut === otherNetworkAccount.network);
if (device && otherNetwork) { if (device && otherNetwork) {
state.warnings.address = `Looks like it's ${device.instanceLabel} Account #${(otherNetworkAccount.index + 1)} address of ${otherNetwork.name} network`; state.warnings.address = `Looks like it's ${device.instanceLabel} Account #${(otherNetworkAccount.index + 1)} address of ${otherNetwork.name} network`;
} }

View File

@ -36,7 +36,7 @@ export type TrezorConnectAction = {
type: typeof CONNECT.INITIALIZATION_ERROR, type: typeof CONNECT.INITIALIZATION_ERROR,
error: string error: string
} | { } | {
type: typeof CONNECT.COIN_CHANGED, type: typeof CONNECT.NETWORK_CHANGED,
payload: { payload: {
network: string network: string
} }

View File

@ -57,15 +57,15 @@ export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction<W
// requested web3 wasn't initialized or is disconnected // requested web3 wasn't initialized or is disconnected
// initialize again // initialize again
const { config, ERC20Abi } = getState().localStorage; const { config, ERC20Abi } = getState().localStorage;
const coin = config.coins.find(c => c.network === network); const networkData = config.networks.find(c => c.shortcut === network);
if (!coin) { if (!networkData) {
// coin not found // network not found
reject(new Error(`Network ${network} not found in application config.`)); reject(new Error(`Network ${network} not found in application config.`));
return; return;
} }
// get first url // get first url
const url = coin.web3[urlIndex]; const url = networkData.web3[urlIndex];
if (!url) { if (!url) {
reject(new Error('Web3 backend is not responding')); reject(new Error('Web3 backend is not responding'));
return; return;
@ -80,7 +80,7 @@ export const initWeb3 = (network: string, urlIndex: number = 0): PromiseAction<W
const newInstance = { const newInstance = {
network, network,
web3, web3,
chainId: coin.chainId, chainId: networkData.chainId,
erc20: new web3.eth.Contract(ERC20Abi), erc20: new web3.eth.Contract(ERC20Abi),
latestBlock, latestBlock,
gasPrice, gasPrice,

View File

@ -10,7 +10,7 @@ export const INITIALIZATION_ERROR: 'connect__init_error' = 'connect__init_error'
export const DEVICE_FROM_STORAGE: 'connect__device_from_storage' = 'connect__device_from_storage'; export const DEVICE_FROM_STORAGE: 'connect__device_from_storage' = 'connect__device_from_storage';
export const AUTH_DEVICE: 'connect__auth_device' = 'connect__auth_device'; export const AUTH_DEVICE: 'connect__auth_device' = 'connect__auth_device';
export const COIN_CHANGED: 'connect__coin_changed' = 'connect__coin_changed'; export const NETWORK_CHANGED: 'connect__network_changed' = 'connect__network_changed';
export const REMEMBER_REQUEST: 'connect__remember_request' = 'connect__remember_request'; export const REMEMBER_REQUEST: 'connect__remember_request' = 'connect__remember_request';
export const FORGET_REQUEST: 'connect__forget_request' = 'connect__forget_request'; export const FORGET_REQUEST: 'connect__forget_request' = 'connect__forget_request';

View File

@ -19,32 +19,21 @@ class CoinLogo extends PureComponent {
this.longIcons = ['etc', 'eth', 'trop']; this.longIcons = ['etc', 'eth', 'trop'];
} }
getIcon() { hasLongIcon(network) {
const { coinNetwork, coinId } = this.props;
let coinImgName = coinNetwork;
if (coinImgName === 'ethereum') {
coinImgName = 'eth';
} else if (coinImgName === 'ethereum-classic') {
coinImgName = 'etc';
}
return coinImgName || coinId;
}
hasLongIcon(coinImgName) {
let hasLongIcon = false; let hasLongIcon = false;
if (this.longIcons.includes(coinImgName)) { if (this.longIcons.includes(network)) {
hasLongIcon = true; hasLongIcon = true;
} }
return hasLongIcon; return hasLongIcon;
} }
render() { render() {
const iconName = this.getIcon(); const { network } = this.props;
return ( return (
<Wrapper> <Wrapper>
<Logo <Logo
hasLongIcon={this.hasLongIcon(iconName)} hasLongIcon={this.hasLongIcon(network)}
src={require(`./images/${iconName}.png`)} // eslint-disable-line src={require(`./images/${network}.png`)} // eslint-disable-line
/> />
</Wrapper> </Wrapper>
); );
@ -52,8 +41,7 @@ class CoinLogo extends PureComponent {
} }
CoinLogo.propTypes = { CoinLogo.propTypes = {
coinId: PropTypes.string, network: PropTypes.string,
coinNetwork: PropTypes.string,
}; };
export default CoinLogo; export default CoinLogo;

View File

@ -20,7 +20,7 @@ export default (props: Props) => {
[{ [{
label: 'Connect', label: 'Connect',
callback: async () => { callback: async () => {
await props.blockchainReconnect(network.network); await props.blockchainReconnect(network.shortcut);
}, },
}] }]
} }

View File

@ -150,7 +150,7 @@ export type Action =
export type State = ReducersState; export type State = ReducersState;
// reexport reduces types // reexport reduces types
export type { Coin } from 'reducers/LocalStorageReducer'; export type { Network } from 'reducers/LocalStorageReducer';
export type { Account } from 'reducers/AccountsReducer'; export type { Account } from 'reducers/AccountsReducer';
export type { Discovery } from 'reducers/DiscoveryReducer'; export type { Discovery } from 'reducers/DiscoveryReducer';
export type { Token } from 'reducers/TokensReducer'; export type { Token } from 'reducers/TokensReducer';

View File

@ -5,7 +5,7 @@ import { BLOCKCHAIN } from 'trezor-connect';
import type { Action } from 'flowtype'; import type { Action } from 'flowtype';
export type BlockchainNetwork = { export type BlockchainNetwork = {
+name: string; +shortcut: string;
connected: boolean; connected: boolean;
} }
@ -13,16 +13,16 @@ export type State = Array<BlockchainNetwork>;
export const initialState: State = []; export const initialState: State = [];
const find = (state: State, name: string): number => state.findIndex(b => b.name === name); const find = (state: State, shortcut: string): number => state.findIndex(b => b.shortcut === shortcut);
const connect = (state: State, action: any): State => { const connect = (state: State, action: any): State => {
const name = action.payload.coin.shortcut.toLowerCase(); const shortcut = action.payload.coin.shortcut.toLowerCase();
const network: BlockchainNetwork = { const network: BlockchainNetwork = {
name, shortcut,
connected: true, connected: true,
}; };
const newState: State = [...state]; const newState: State = [...state];
const index: number = find(newState, name); const index: number = find(newState, shortcut);
if (index >= 0) { if (index >= 0) {
newState[index] = network; newState[index] = network;
} else { } else {
@ -32,13 +32,13 @@ const connect = (state: State, action: any): State => {
}; };
const disconnect = (state: State, action: any): State => { const disconnect = (state: State, action: any): State => {
const name = action.payload.coin.shortcut.toLowerCase(); const shortcut = action.payload.coin.shortcut.toLowerCase();
const network: BlockchainNetwork = { const network: BlockchainNetwork = {
name, shortcut,
connected: false, connected: false,
}; };
const newState: State = [...state]; const newState: State = [...state];
const index: number = find(newState, name); const index: number = find(newState, shortcut);
if (index >= 0) { if (index >= 0) {
newState[index] = network; newState[index] = network;
} else { } else {

View File

@ -5,9 +5,9 @@ import * as STORAGE from 'actions/constants/localStorage';
import type { Action } from 'flowtype'; import type { Action } from 'flowtype';
export type Coin = { export type Network = {
name: string; name: string;
network: string; shortcut: string;
symbol: string; symbol: string;
bip44: string; bip44: string;
defaultGasLimit: number; defaultGasLimit: number;
@ -57,40 +57,27 @@ export type FiatValueTicker = {
} }
export type Config = { export type Config = {
coins: Array<Coin>; networks: Array<Network>;
fiatValueTickers: Array<FiatValueTicker>; fiatValueTickers: Array<FiatValueTicker>;
} }
export type CustomBackend = {
name: string;
url: string;
}
export type State = { export type State = {
initialized: boolean; initialized: boolean;
error: ?string; error: ?string;
config: Config; config: Config;
ERC20Abi: Array<Object>; ERC20Abi: Array<Object>;
tokens: TokensCollection; tokens: TokensCollection;
customBackend: Array<CustomBackend>;
} }
const initialState: State = { const initialState: State = {
initialized: false, initialized: false,
error: null, error: null,
config: { config: {
coins: [], networks: [],
fiatValueTickers: [], fiatValueTickers: [],
}, },
ERC20Abi: [], ERC20Abi: [],
tokens: {}, tokens: {},
customBackend: [
{
name: 'Custom1',
slug: 'custom1',
url: 'http://google.com',
},
],
}; };
export default function localStorage(state: State = initialState, action: Action): State { export default function localStorage(state: State = initialState, action: Action): State {

View File

@ -4,7 +4,7 @@ import * as ACCOUNT from 'actions/constants/account';
import type { import type {
Action, Action,
Account, Account,
Coin, Network,
Token, Token,
PendingTx, PendingTx,
Discovery, Discovery,
@ -13,7 +13,7 @@ import type {
export type State = { export type State = {
location: string; location: string;
account: ?Account; account: ?Account;
network: ?Coin; network: ?Network;
tokens: Array<Token>, tokens: Array<Token>,
pending: Array<PendingTx>, pending: Array<PendingTx>,
discovery: ?Discovery, discovery: ?Discovery,

View File

@ -6,7 +6,7 @@ import type {
Device, Device,
TrezorDevice, TrezorDevice,
Account, Account,
Coin, Network,
Discovery, Discovery,
Token, Token,
PendingTx, PendingTx,
@ -66,13 +66,13 @@ export const getSelectedAccount = (state: State): ?Account => {
return state.accounts.find(a => a.deviceState === device.state && a.index === index && a.network === locationState.network); return state.accounts.find(a => a.deviceState === device.state && a.index === index && a.network === locationState.network);
}; };
export const getSelectedNetwork = (state: State): ?Coin => { export const getSelectedNetwork = (state: State): ?Network => {
const device = state.wallet.selectedDevice; const device = state.wallet.selectedDevice;
const { coins } = state.localStorage.config; const { networks } = state.localStorage.config;
const locationState = state.router.location.state; const locationState = state.router.location.state;
if (!device || !locationState.network) return null; if (!device || !locationState.network) return null;
return coins.find(c => c.network === locationState.network); return networks.find(c => c.shortcut === locationState.network);
}; };
export const getDiscoveryProcess = (state: State): ?Discovery => { export const getDiscoveryProcess = (state: State): ?Discovery => {

View File

@ -70,10 +70,10 @@ const WalletService: Middleware = (api: MiddlewareAPI) => (next: MiddlewareDispa
const prevLocation = prevState.router.location; const prevLocation = prevState.router.location;
const currentLocation = api.getState().router.location; const currentLocation = api.getState().router.location;
if (action.type === LOCATION_CHANGE && prevLocation.pathname !== currentLocation.pathname) { if (action.type === LOCATION_CHANGE && prevLocation.pathname !== currentLocation.pathname) {
// watch for coin change // watch for network change
if (prevLocation.state.network !== currentLocation.state.network) { if (prevLocation.state.network !== currentLocation.state.network) {
api.dispatch({ api.dispatch({
type: CONNECT.COIN_CHANGED, type: CONNECT.NETWORK_CHANGED,
payload: { payload: {
network: currentLocation.state.network, network: currentLocation.state.network,
}, },

View File

@ -115,11 +115,11 @@ const AccountMenu = (props: Props) => {
const baseUrl: string = urlParams.deviceInstance ? `/device/${urlParams.device}:${urlParams.deviceInstance}` : `/device/${urlParams.device}`; const baseUrl: string = urlParams.deviceInstance ? `/device/${urlParams.device}:${urlParams.deviceInstance}` : `/device/${urlParams.device}`;
const { config } = props.localStorage; const { config } = props.localStorage;
const selectedCoin = config.coins.find(c => c.network === location.state.network); const network = config.networks.find(c => c.shortcut === location.state.network);
if (!selected || !selectedCoin) return null; if (!selected || !network) return null;
const fiatRate = props.fiat.find(f => f.network === selectedCoin.network); const fiatRate = props.fiat.find(f => f.network === network.shortcut);
const deviceAccounts: Accounts = findDeviceAccounts(accounts, selected, location.state.network); const deviceAccounts: Accounts = findDeviceAccounts(accounts, selected, location.state.network);
@ -130,14 +130,14 @@ const AccountMenu = (props: Props) => {
let balance: string = 'Loading...'; let balance: string = 'Loading...';
if (account.balance !== '') { if (account.balance !== '') {
const pending = stateUtils.getAccountPendingTx(props.pending, account); const pending = stateUtils.getAccountPendingTx(props.pending, account);
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, selectedCoin.symbol); const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol);
const availableBalance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10); const availableBalance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10);
balance = `${availableBalance} ${selectedCoin.symbol}`; balance = `${availableBalance} ${network.symbol}`;
if (fiatRate) { if (fiatRate) {
const accountBalance = new BigNumber(availableBalance); const accountBalance = new BigNumber(availableBalance);
const fiat = accountBalance.times(fiatRate.value).toFixed(2); const fiat = accountBalance.times(fiatRate.value).toFixed(2);
balance = `${availableBalance} ${selectedCoin.symbol} / $${fiat}`; balance = `${availableBalance} ${network.symbol} / $${fiat}`;
} }
} }
@ -233,21 +233,19 @@ const AccountMenu = (props: Props) => {
return ( return (
<Wrapper> <Wrapper>
{selectedCoin && ( <NavLink to={baseUrl}>
<NavLink to={baseUrl}> <RowCoin
<RowCoin network={{
coin={{ name: network.name,
name: selectedCoin.name, shortcut: network.shortcut,
network: selectedCoin.network, }}
}} iconLeft={{
iconLeft={{ type: ICONS.ARROW_LEFT,
type: ICONS.ARROW_LEFT, color: colors.TEXT_PRIMARY,
color: colors.TEXT_PRIMARY, size: 20,
size: 20, }}
}} />
/> </NavLink>
</NavLink>
)}
<Wrapper> <Wrapper>
{selectedAccounts} {selectedAccounts}
</Wrapper> </Wrapper>

View File

@ -37,9 +37,9 @@ class CoinMenu extends PureComponent<Props> {
return coins.map((coin) => { return coins.map((coin) => {
const row = ( const row = (
<RowCoin <RowCoin
coin={{ network={{
name: coin.coinName, name: coin.coinName,
id: coin.id, shortcut: coin.id,
}} }}
iconRight={{ iconRight={{
type: ICONS.SKIP, type: ICONS.SKIP,
@ -58,15 +58,15 @@ class CoinMenu extends PureComponent<Props> {
const { config } = this.props.localStorage; const { config } = this.props.localStorage;
return ( return (
<Wrapper> <Wrapper>
{config.coins.map(item => ( {config.networks.map(item => (
<NavLink <NavLink
key={item.network} key={item.shortcut}
to={`${this.getBaseUrl()}/network/${item.network}/account/0`} to={`${this.getBaseUrl()}/network/${item.shortcut}/account/0`}
> >
<RowCoin <RowCoin
coin={{ network={{
name: item.name, name: item.name,
network: item.network, shortcut: item.shortcut,
}} }}
/> />
</NavLink> </NavLink>

View File

@ -38,7 +38,7 @@ const IconWrapper = styled.div`
`; `;
const RowCoin = ({ const RowCoin = ({
coin, iconLeft, iconRight, network, iconLeft, iconRight,
}) => ( }) => (
<RowCoinWrapper> <RowCoinWrapper>
<Row> <Row>
@ -53,11 +53,8 @@ const RowCoin = ({
</IconWrapper> </IconWrapper>
)} )}
<CoinNameWrapper> <CoinNameWrapper>
<CoinLogo <CoinLogo network={network.shortcut} />
coinNetwork={coin.network} <p>{network.name}</p>
coinId={coin.id}
/>
<p>{coin.name}</p>
</CoinNameWrapper> </CoinNameWrapper>
</Left> </Left>
{iconRight && ( {iconRight && (
@ -77,10 +74,9 @@ const iconShape = {
size: PropTypes.number.isRequired, size: PropTypes.number.isRequired,
}; };
RowCoin.propTypes = { RowCoin.propTypes = {
coin: PropTypes.shape({ network: PropTypes.shape({
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
network: PropTypes.string, shortcut: PropTypes.string,
id: PropTypes.string,
}).isRequired, }).isRequired,
iconLeft: PropTypes.shape(iconShape), iconLeft: PropTypes.shape(iconShape),
iconRight: PropTypes.shape(iconShape), iconRight: PropTypes.shape(iconShape),

View File

@ -7,14 +7,14 @@ import { H2 } from 'components/Heading';
import Link from 'components/Link'; import Link from 'components/Link';
import ScaleText from 'react-scale-text'; import ScaleText from 'react-scale-text';
import type { Coin } from 'reducers/LocalStorageReducer'; import type { Network } from 'reducers/LocalStorageReducer';
import type { Token } from 'reducers/TokensReducer'; import type { Token } from 'reducers/TokensReducer';
import type { Props as BaseProps } from '../../Container'; import type { Props as BaseProps } from '../../Container';
type Props = { type Props = {
pending: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'pending'>, pending: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'pending'>,
tokens: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'tokens'>, tokens: $PropertyType<$ElementType<BaseProps, 'selectedAccount'>, 'tokens'>,
network: Coin network: Network
} }
const Wrapper = styled.div` const Wrapper = styled.div`

View File

@ -7,11 +7,11 @@ import colors from 'config/colors';
import ICONS from 'config/icons'; import ICONS from 'config/icons';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables'; import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import type { Coin } from 'reducers/LocalStorageReducer'; import type { Network } from 'flowtype';
import type { Props as BaseProps } from '../../Container'; import type { Props as BaseProps } from '../../Container';
type Props = { type Props = {
coin: Coin, network: Network,
balance: string, balance: string,
fiat: $ElementType<BaseProps, 'fiat'>, fiat: $ElementType<BaseProps, 'fiat'>,
} }
@ -77,7 +77,7 @@ const BalanceRateWrapper = styled(BalanceWrapper)`
padding-left: 50px; padding-left: 50px;
`; `;
const CoinBalace = styled.div` const CoinBalance = styled.div`
font-size: ${FONT_SIZE.SMALLER}; font-size: ${FONT_SIZE.SMALLER};
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
`; `;
@ -97,7 +97,7 @@ class AccountBalance extends PureComponent<Props, State> {
}; };
} }
handleHideBallanceIconClick() { handleHideBalanceIconClick() {
this.setState(previousState => ({ this.setState(previousState => ({
isHidden: !previousState.isHidden, isHidden: !previousState.isHidden,
canAnimateHideBalanceIcon: true, canAnimateHideBalanceIcon: true,
@ -105,8 +105,8 @@ class AccountBalance extends PureComponent<Props, State> {
} }
render() { render() {
const selectedCoin = this.props.coin; const { network } = this.props;
const fiatRate: any = this.props.fiat.find(f => f.network === selectedCoin.network); const fiatRate: any = this.props.fiat.find(f => f.network === network.shortcut);
let accountBalance = ''; let accountBalance = '';
let fiatRateValue = ''; let fiatRateValue = '';
@ -121,7 +121,7 @@ class AccountBalance extends PureComponent<Props, State> {
return ( return (
<Wrapper> <Wrapper>
<HideBalanceIconWrapper <HideBalanceIconWrapper
onClick={() => this.handleHideBallanceIconClick()} onClick={() => this.handleHideBalanceIconClick()}
> >
<Icon <Icon
canAnimate={this.state.canAnimateHideBalanceIcon} canAnimate={this.state.canAnimateHideBalanceIcon}
@ -138,13 +138,13 @@ class AccountBalance extends PureComponent<Props, State> {
{fiatRate && ( {fiatRate && (
<FiatValue>${fiat}</FiatValue> <FiatValue>${fiat}</FiatValue>
)} )}
<CoinBalace>{this.props.balance} {selectedCoin.symbol}</CoinBalace> <CoinBalance>{this.props.balance} {network.symbol}</CoinBalance>
</BalanceWrapper> </BalanceWrapper>
{fiatRate && ( {fiatRate && (
<BalanceRateWrapper> <BalanceRateWrapper>
<Label>Rate</Label> <Label>Rate</Label>
<FiatValueRate>${fiatRateValue}</FiatValueRate> <FiatValueRate>${fiatRateValue}</FiatValueRate>
<CoinBalace>1.00 {selectedCoin.symbol}</CoinBalace> <CoinBalance>1.00 {network.symbol}</CoinBalance>
</BalanceRateWrapper> </BalanceRateWrapper>
)} )}
</React.Fragment> </React.Fragment>

View File

@ -81,18 +81,15 @@ const AccountSummary = (props: Props) => {
<React.Fragment> <React.Fragment>
<AccountHeading> <AccountHeading>
<AccountName> <AccountName>
<StyledCoinLogo coinNetwork={account.network} /> <StyledCoinLogo network={account.network} />
<H2>Account #{parseInt(account.index, 10) + 1}</H2> <H2>Account #{parseInt(account.index, 10) + 1}</H2>
</AccountName> </AccountName>
<Link href={explorerLink} isGray>See full transaction history</Link> <Link href={explorerLink} isGray>See full transaction history</Link>
</AccountHeading> </AccountHeading>
<AccountBalance <AccountBalance
coin={network} network={network}
summary={props.summary}
balance={balance} balance={balance}
network={network.network}
fiat={props.fiat} fiat={props.fiat}
localStorage={props.localStorage}
/> />
<H2Wrapper> <H2Wrapper>
<H2>Tokens</H2> <H2>Tokens</H2>
@ -108,11 +105,6 @@ const AccountSummary = (props: Props) => {
/> />
</StyledTooltip> </StyledTooltip>
</H2Wrapper> </H2Wrapper>
{/* 0x58cda554935e4a1f2acbe15f8757400af275e084 Lahod */}
{/* 0x58cda554935e4a1f2acbe15f8757400af275e084 T01 */}
{/* TOOO: AsyncSelect is lagging when dropdown menu must show more than 200 items */}
{/* TODO: Input's box-shadow */}
<AsyncSelectWrapper> <AsyncSelectWrapper>
<AsyncSelect <AsyncSelect
isSearchable isSearchable