From 31e3c7a9a23052f9c2887f2c5d1999cf85aff8de Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Fri, 21 Dec 2018 10:58:53 +0100 Subject: [PATCH 1/2] refactoring Account object to coin specific --- src/actions/AccountsActions.js | 54 +------------ src/actions/LocalStorageActions.js | 2 +- src/actions/SessionStorageActions.js | 2 +- src/actions/TokenActions.js | 4 +- src/actions/Web3Actions.js | 7 +- src/actions/ethereum/BlockchainActions.js | 4 +- src/actions/ethereum/DiscoveryActions.js | 25 ++++--- src/actions/ethereum/SendFormActions.js | 14 ++-- .../ethereum/SendFormValidationActions.js | 8 +- src/actions/ripple/BlockchainActions.js | 8 +- src/actions/ripple/DiscoveryActions.js | 17 +++-- src/actions/ripple/SendFormActions.js | 4 +- .../ripple/SendFormValidationActions.js | 4 +- .../modals/confirm/Address/index.js | 2 +- .../modals/confirm/UnverifiedAddress/index.js | 2 +- src/reducers/AccountsReducer.js | 75 ++++++++----------- src/reducers/TokensReducer.js | 12 +-- src/reducers/utils/index.js | 4 +- src/services/LocalStorageService.js | 3 +- .../components/AccountMenu/index.js | 4 +- .../views/Account/Receive/ethereum/index.js | 10 +-- .../views/Account/Receive/ripple/index.js | 10 +-- .../Wallet/views/Account/SignVerify/index.js | 4 +- .../views/Account/Summary/ethereum/index.js | 2 +- .../views/Account/Summary/ripple/index.js | 2 +- 25 files changed, 110 insertions(+), 173 deletions(-) diff --git a/src/actions/AccountsActions.js b/src/actions/AccountsActions.js index 27d4c46b..6b918df8 100644 --- a/src/actions/AccountsActions.js +++ b/src/actions/AccountsActions.js @@ -4,59 +4,13 @@ import * as ACCOUNT from 'actions/constants/account'; import type { Action } from 'flowtype'; import type { Account, State } from 'reducers/AccountsReducer'; -export type AccountFromStorageAction = { +export type AccountAction = { type: typeof ACCOUNT.FROM_STORAGE, payload: State -} - -export type AccountCreateAction = { - type: typeof ACCOUNT.CREATE, +} | { + type: typeof ACCOUNT.CREATE | typeof ACCOUNT.UPDATE, payload: Account, -} - -export type AccountUpdateAction = { - type: typeof ACCOUNT.UPDATE, - payload: Account, -} - -export type AccountSetBalanceAction = { - type: typeof ACCOUNT.SET_BALANCE, - address: string, - network: string, - deviceState: string, - balance: string -} - -export type AccountSetNonceAction = { - type: typeof ACCOUNT.SET_NONCE, - address: string, - network: string, - deviceState: string, - nonce: number -} - -export type AccountAction = - AccountFromStorageAction - | AccountCreateAction - | AccountUpdateAction - | AccountSetBalanceAction - | AccountSetNonceAction; - -export const setBalance = (address: string, network: string, deviceState: string, balance: string): Action => ({ - type: ACCOUNT.SET_BALANCE, - address, - network, - deviceState, - balance, -}); - -export const setNonce = (address: string, network: string, deviceState: string, nonce: number): Action => ({ - type: ACCOUNT.SET_NONCE, - address, - network, - deviceState, - nonce, -}); +}; export const update = (account: Account): Action => ({ type: ACCOUNT.UPDATE, diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index c3380891..fe71ea58 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -63,7 +63,7 @@ const findTokens = (accounts: Array, tokens: Array): Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(d => d.deviceState === dev.state && d.completed)), []); -const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.address && p.network === account.network)), []); +const findPendingTxs = (accounts: Array, pending: Array): Array => accounts.reduce((result, account) => result.concat(pending.filter(p => p.address === account.descriptor && p.network === account.network)), []); export const save = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { const devices: Array = getState().devices.filter(d => d.features && d.remember === true); diff --git a/src/actions/SessionStorageActions.js b/src/actions/SessionStorageActions.js index 3686d8f4..fcccd0d4 100644 --- a/src/actions/SessionStorageActions.js +++ b/src/actions/SessionStorageActions.js @@ -44,7 +44,7 @@ export const loadEthereumDraftTransaction = (): PayloadAction async name: token.name, symbol: token.symbol, address: token.address, - ethAddress: account.address, + ethAddress: account.descriptor, decimals: token.decimals, balance: '0', }; @@ -87,7 +87,7 @@ export const add = (token: NetworkToken, account: Account): AsyncAction => async }); const tokenBalance = await dispatch(BlockchainActions.getTokenBalance(tkn)); - dispatch(setBalance(token.address, account.address, tokenBalance)); + dispatch(setBalance(token.address, account.descriptor, tokenBalance)); }; export const remove = (token: Token): Action => ({ diff --git a/src/actions/Web3Actions.js b/src/actions/Web3Actions.js index dd665224..2bb0a43e 100644 --- a/src/actions/Web3Actions.js +++ b/src/actions/Web3Actions.js @@ -193,9 +193,10 @@ export const getTxInput = (): PromiseAction => async (dispatch: Dispatch): export const updateAccount = (account: Account, newAccount: EthereumAccount, network: string): PromiseAction => async (dispatch: Dispatch): Promise => { const instance: Web3Instance = await dispatch(initWeb3(network)); - const balance = await instance.web3.eth.getBalance(account.address); - const nonce = await instance.web3.eth.getTransactionCount(account.address); + const balance = await instance.web3.eth.getBalance(account.descriptor); + const nonce = await instance.web3.eth.getTransactionCount(account.descriptor); dispatch(AccountsActions.update({ + networkType: 'ethereum', ...account, ...newAccount, nonce, @@ -208,7 +209,7 @@ export const updateAccount = (account: Account, newAccount: EthereumAccount, net }; export const updateAccountTokens = (account: Account): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const tokens = getState().tokens.filter(t => t.network === account.network && t.ethAddress === account.address); + const tokens = getState().tokens.filter(t => t.network === account.network && t.ethAddress === account.descriptor); tokens.forEach(async (token) => { const balance = await dispatch(getTokenBalance(token)); // const newBalance: string = balance.dividedBy(Math.pow(10, token.decimals)).toString(10); diff --git a/src/actions/ethereum/BlockchainActions.js b/src/actions/ethereum/BlockchainActions.js index 72dec1d7..b1856d24 100644 --- a/src/actions/ethereum/BlockchainActions.js +++ b/src/actions/ethereum/BlockchainActions.js @@ -85,7 +85,7 @@ export const estimateGasLimit = (network: string, data: string, value: string, g }; export const subscribe = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const accounts: Array = getState().accounts.filter(a => a.network === network).map(a => a.address); // eslint-disable-line no-unused-vars + const accounts: Array = getState().accounts.filter(a => a.network === network).map(a => a.descriptor); // eslint-disable-line no-unused-vars const response = await TrezorConnect.blockchainSubscribe({ accounts, coin: network, @@ -129,7 +129,7 @@ export const onBlockMined = (network: string): PromiseAction => async (dis export const onNotification = (payload: $ElementType): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { const { notification } = payload; - const account = getState().accounts.find(a => a.address === notification.address); + const account = getState().accounts.find(a => a.descriptor === notification.address); if (!account) return; if (notification.status === 'pending') { diff --git a/src/actions/ethereum/DiscoveryActions.js b/src/actions/ethereum/DiscoveryActions.js index e4b302b2..e1f71f83 100644 --- a/src/actions/ethereum/DiscoveryActions.js +++ b/src/actions/ethereum/DiscoveryActions.js @@ -8,13 +8,13 @@ import * as BlockchainActions from 'actions/ethereum/BlockchainActions'; import type { PromiseAction, Dispatch, + GetState, TrezorDevice, Network, Account, } from 'flowtype'; import type { Discovery } from 'reducers/DiscoveryReducer'; - export type DiscoveryStartAction = { type: typeof DISCOVERY.START, networkType: 'ethereum', @@ -61,33 +61,38 @@ export const begin = (device: TrezorDevice, network: Network): PromiseAction => async (dispatch: Dispatch): Promise => { +export const discoverAccount = (device: TrezorDevice, discoveryProcess: Discovery): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { + const { config } = getState().localStorage; + const network = config.networks.find(c => c.shortcut === discoveryProcess.network); + if (!network) throw new Error('Discovery network not found'); + const derivedKey = discoveryProcess.hdKey.derive(`m/${discoveryProcess.accountIndex}`); const path = discoveryProcess.basePath.concat(discoveryProcess.accountIndex); const publicAddress: string = EthereumjsUtil.publicToAddress(derivedKey.publicKey, true).toString('hex'); const ethAddress: string = EthereumjsUtil.toChecksumAddress(publicAddress); - const { network } = discoveryProcess; // TODO: check if address was created before - const account = await dispatch(BlockchainActions.discoverAccount(device, ethAddress, network)); + const account = await dispatch(BlockchainActions.discoverAccount(device, ethAddress, network.shortcut)); // const accountIsEmpty = account.transactions <= 0 && account.nonce <= 0 && account.balance === '0'; const empty = account.nonce <= 0 && account.balance === '0'; return { + imported: false, index: discoveryProcess.accountIndex, - loaded: true, - network, + network: network.shortcut, deviceID: device.features ? device.features.device_id : '0', deviceState: device.state || '0', - addressPath: path, - address: ethAddress, + accountPath: path, + descriptor: ethAddress, + balance: account.balance, availableBalance: account.balance, - sequence: account.nonce, - nonce: account.nonce, block: account.block, transactions: account.transactions, empty, + + networkType: 'ethereum', + nonce: account.nonce, }; }; \ No newline at end of file diff --git a/src/actions/ethereum/SendFormActions.js b/src/actions/ethereum/SendFormActions.js index 6ce41239..5c8fb2e3 100644 --- a/src/actions/ethereum/SendFormActions.js +++ b/src/actions/ethereum/SendFormActions.js @@ -76,7 +76,7 @@ export const observe = (prevState: ReducersState, action: Action): ThunkAction = // make sure that this token is added into account const { account, tokens } = getState().selectedAccount; if (!account) return; - const token = findToken(tokens, account.address, currentState.sendFormEthereum.currency, account.deviceState); + const token = findToken(tokens, account.descriptor, currentState.sendFormEthereum.currency, account.deviceState); if (!token) { // token not found, re-init form dispatch(init()); @@ -456,7 +456,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge pending, } = getState().selectedAccount; - if (!account || !network) return; + if (!account || account.networkType !== 'ethereum' || !network) return; const currentState: State = getState().sendFormEthereum; @@ -466,8 +466,8 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge const txData = await dispatch(prepareEthereumTx({ network: network.shortcut, - token: isToken ? findToken(getState().tokens, account.address, currentState.currency, account.deviceState) : null, - from: account.address, + token: isToken ? findToken(getState().tokens, account.descriptor, currentState.currency, account.deviceState) : null, + from: account.descriptor, to: currentState.address, amount: currentState.amount, data: currentState.data, @@ -487,7 +487,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge }, // useEmptyPassphrase: !selected.instance, useEmptyPassphrase: selected.useEmptyPassphrase, - path: account.addressPath, + path: account.accountPath, transaction: txData, }); @@ -533,10 +533,10 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge type: 'send', status: 'pending', confirmations: 0, - address: account.address, + address: account.descriptor, inputs: [ { - addresses: [account.address], + addresses: [account.descriptor], amount: currentState.amount, fee, total: currentState.total, diff --git a/src/actions/ethereum/SendFormValidationActions.js b/src/actions/ethereum/SendFormValidationActions.js index b7985b09..1720ce23 100644 --- a/src/actions/ethereum/SendFormValidationActions.js +++ b/src/actions/ethereum/SendFormValidationActions.js @@ -114,7 +114,7 @@ export const recalculateTotalAmount = ($state: State): PayloadAction => ( if (state.setMax) { const pendingAmount = getPendingAmount(pending, state.currency, isToken); if (isToken) { - const token = findToken(tokens, account.address, state.currency, account.deviceState); + const token = findToken(tokens, account.descriptor, state.currency, account.deviceState); if (token) { state.amount = new BigNumber(token.balance).minus(pendingAmount).toString(10); } @@ -173,7 +173,7 @@ export const addressLabel = ($state: State): PayloadAction => (dispatch: if (!account || !network) return state; const { address } = state; - const savedAccounts = getState().accounts.filter(a => a.address.toLowerCase() === address.toLowerCase()); + const savedAccounts = getState().accounts.filter(a => a.descriptor.toLowerCase() === address.toLowerCase()); if (savedAccounts.length > 0) { // check if found account belongs to this network const currentNetworkAccount = savedAccounts.find(a => a.network === network.shortcut); @@ -221,7 +221,7 @@ export const amountValidation = ($state: State): PayloadAction => (dispat const pendingAmount: BigNumber = getPendingAmount(pending, state.currency, isToken); if (isToken) { - const token = findToken(tokens, account.address, state.currency, account.deviceState); + const token = findToken(tokens, account.descriptor, state.currency, account.deviceState); if (!token) return state; const decimalRegExp = dynamicRegexp(parseInt(token.decimals, 0)); @@ -304,7 +304,7 @@ export const nonceValidation = ($state: State): PayloadAction => (dispatc const { account, } = getState().selectedAccount; - if (!account) return state; + if (!account || account.networkType !== 'ethereum') return state; const { nonce } = state; if (nonce.length < 1) { diff --git a/src/actions/ripple/BlockchainActions.js b/src/actions/ripple/BlockchainActions.js index 5cb6cede..5d73bd8b 100644 --- a/src/actions/ripple/BlockchainActions.js +++ b/src/actions/ripple/BlockchainActions.js @@ -16,7 +16,7 @@ import type { const DECIMALS: number = 6; export const subscribe = (network: string): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { - const accounts: Array = getState().accounts.filter(a => a.network === network).map(a => a.address); + const accounts: Array = getState().accounts.filter(a => a.network === network).map(a => a.descriptor); await TrezorConnect.blockchainSubscribe({ accounts, coin: network, @@ -68,7 +68,7 @@ export const onBlockMined = (network: string): PromiseAction => async (dis export const onNotification = (payload: $ElementType): PromiseAction => async (dispatch: Dispatch, getState: GetState): Promise => { const { notification } = payload; - const account = getState().accounts.find(a => a.address === notification.address); + const account = getState().accounts.find(a => a.descriptor === notification.address); if (!account) return; if (notification.status === 'pending') { @@ -95,7 +95,7 @@ export const onNotification = (payload: $ElementType async (dispatch: Dispatch, getState: Ge const selected: ?TrezorDevice = getState().wallet.selectedDevice; if (!selected) return; - if (!account || !network) return; + if (!account || account.networkType !== 'ripple' || !network) return; const blockchain = getState().blockchain.find(b => b.shortcut === account.network); if (!blockchain) return; @@ -188,7 +188,7 @@ export const onSend = (): AsyncAction => async (dispatch: Dispatch, getState: Ge state: selected.state, }, useEmptyPassphrase: selected.useEmptyPassphrase, - path: account.addressPath, + path: account.accountPath, transaction: { fee: blockchain.fee, // Fee must be in the range of 10 to 10,000 drops flags: 0x80000000, diff --git a/src/actions/ripple/SendFormValidationActions.js b/src/actions/ripple/SendFormValidationActions.js index 9c5f1b01..fd473181 100644 --- a/src/actions/ripple/SendFormValidationActions.js +++ b/src/actions/ripple/SendFormValidationActions.js @@ -115,7 +115,7 @@ const addressValidation = ($state: State): PayloadAction => (dispatch: Di state.errors.address = 'Address is not set'; } else if (!AddressValidator.validate(address, 'XRP')) { state.errors.address = 'Address is not valid'; - } else if (address.toLowerCase() === account.address.toLowerCase()) { + } else if (address.toLowerCase() === account.descriptor.toLowerCase()) { state.errors.address = 'Cannot send to myself'; } return state; @@ -135,7 +135,7 @@ const addressLabel = ($state: State): PayloadAction => (dispatch: Dispatc if (!account || !network) return state; const { address } = state; - const savedAccounts = getState().accounts.filter(a => a.address.toLowerCase() === address.toLowerCase()); + const savedAccounts = getState().accounts.filter(a => a.descriptor.toLowerCase() === address.toLowerCase()); if (savedAccounts.length > 0) { // check if found account belongs to this network const currentNetworkAccount = savedAccounts.find(a => a.network === network.shortcut); diff --git a/src/components/modals/confirm/Address/index.js b/src/components/modals/confirm/Address/index.js index d3b0f1cf..97538a97 100644 --- a/src/components/modals/confirm/Address/index.js +++ b/src/components/modals/confirm/Address/index.js @@ -45,7 +45,7 @@ const ConfirmAddress = (props: Props) => {

Please compare your address on device with address shown bellow.

-

{ account.address }

+

{ account.descriptor }

diff --git a/src/components/modals/confirm/UnverifiedAddress/index.js b/src/components/modals/confirm/UnverifiedAddress/index.js index cb7c7e7b..2246cdf1 100644 --- a/src/components/modals/confirm/UnverifiedAddress/index.js +++ b/src/components/modals/confirm/UnverifiedAddress/index.js @@ -71,7 +71,7 @@ class ConfirmUnverifiedAddress extends PureComponent { const { account, onCancel, showAddress } = this.props; if (!account) return; onCancel(); - showAddress(account.addressPath); + showAddress(account.accountPath); } showUnverifiedAddress() { diff --git a/src/reducers/AccountsReducer.js b/src/reducers/AccountsReducer.js index e2fb75f3..f52f22c8 100644 --- a/src/reducers/AccountsReducer.js +++ b/src/reducers/AccountsReducer.js @@ -6,27 +6,35 @@ import * as WALLET from 'actions/constants/wallet'; import * as ACCOUNT from 'actions/constants/account'; import type { Action, TrezorDevice } from 'flowtype'; -import type { - AccountSetBalanceAction, - AccountSetNonceAction, -} from 'actions/AccountsActions'; -export type Account = { - loaded: boolean; - +network: string; - +deviceID: string; - +deviceState: string; - +index: number; - +addressPath: Array; - +address: string; - balance: string; - availableBalance: string; - sequence: number; - nonce: number; - block: number; - transactions: number; - empty: boolean; -} +type AccountCommon = { + +imported: boolean, + +index: number, + +network: string, // network id (shortcut) + +deviceID: string, // empty for imported accounts + +deviceState: string, // empty for imported accounts + +accountPath: Array, // empty for imported accounts + +descriptor: string, // address or xpub + + balance: string, + availableBalance: string, // balance - pending + block: number, // last known (synchronized) block + empty: boolean, // account without transactions + + transactions: number, // deprecated +}; + +export type Account = AccountCommon & { + networkType: 'ethereum', + nonce: number, +} | AccountCommon & { + networkType: 'ripple', + sequence: number, + reserve: string, +} | AccountCommon & { + networkType: 'bitcoin', + addressIndex: number, +}; export type State = Array; @@ -44,7 +52,7 @@ export const findDeviceAccounts = (state: State, device: TrezorDevice, network: const createAccount = (state: State, account: Account): State => { // TODO check with device_id // check if account was created before - const exist: ?Account = state.find(a => a.address === account.address && a.network === account.network && a.deviceState === account.deviceState); + const exist: ?Account = state.find(a => a.descriptor === account.descriptor && a.network === account.network && a.deviceState === account.deviceState); if (exist) { return state; } @@ -55,7 +63,6 @@ const createAccount = (state: State, account: Account): State => { const removeAccounts = (state: State, device: TrezorDevice): State => state.filter(account => account.deviceState !== device.state); - const clear = (state: State, devices: Array): State => { let newState: State = [...state]; devices.forEach((d) => { @@ -65,29 +72,12 @@ const clear = (state: State, devices: Array): State => { }; const updateAccount = (state: State, account: Account): State => { - const index: number = state.findIndex(a => a.address === account.address && a.network === account.network && a.deviceState === account.deviceState); + const index: number = state.findIndex(a => a.descriptor === account.descriptor && a.network === account.network && a.deviceState === account.deviceState); const newState: State = [...state]; newState[index] = account; return newState; }; -const setBalance = (state: State, action: AccountSetBalanceAction): State => { - // const index: number = state.findIndex(account => account.address === action.address && account.network === action.network && account.deviceState === action.deviceState); - const index: number = state.findIndex(account => account.address === action.address && account.network === action.network); - const newState: State = [...state]; - newState[index].loaded = true; - newState[index].balance = action.balance; - return newState; -}; - -const setNonce = (state: State, action: AccountSetNonceAction): State => { - const index: number = state.findIndex(account => account.address === action.address && account.network === action.network && account.deviceState === action.deviceState); - const newState: State = [...state]; - newState[index].loaded = true; - newState[index].nonce = action.nonce; - return newState; -}; - export default (state: State = initialState, action: Action): State => { switch (action.type) { case ACCOUNT.CREATE: @@ -108,11 +98,6 @@ export default (state: State = initialState, action: Action): State => { case ACCOUNT.UPDATE: return updateAccount(state, action.payload); - case ACCOUNT.SET_BALANCE: - return setBalance(state, action); - case ACCOUNT.SET_NONCE: - return setNonce(state, action); - case ACCOUNT.FROM_STORAGE: return action.payload; diff --git a/src/reducers/TokensReducer.js b/src/reducers/TokensReducer.js index c880c588..847a7bbd 100644 --- a/src/reducers/TokensReducer.js +++ b/src/reducers/TokensReducer.js @@ -27,17 +27,7 @@ const initialState: State = []; // Helper for actions export const findToken = (state: Array, address: string, symbol: string, deviceState: string): ?Token => state.find(t => t.ethAddress === address && t.symbol === symbol && t.deviceState === deviceState); -export const findAccountTokens = (state: Array, account: Account): Array => state.filter(t => t.ethAddress === account.address && t.network === account.network && t.deviceState === account.deviceState); - -// const setBalance = (state: State, payload: any): State => { -// const newState: Array = [ ...state ]; -// let index: number = state.findIndex(t => t.address === payload.address && t.ethAddress === payload.ethAddress); -// if (index >= 0) { -// newState[index].loaded = true; -// newState[index].balance = payload.balance; -// } -// return newState; -// } +export const findAccountTokens = (state: Array, account: Account): Array => state.filter(t => t.ethAddress === account.descriptor && t.network === account.network && t.deviceState === account.deviceState); const create = (state: State, token: Token): State => { const newState: State = [...state]; diff --git a/src/reducers/utils/index.js b/src/reducers/utils/index.js index f3734dad..d01e6568 100644 --- a/src/reducers/utils/index.js +++ b/src/reducers/utils/index.js @@ -86,7 +86,7 @@ export const getDiscoveryProcess = (state: State): ?Discovery => { export const getAccountPendingTx = (pending: Array, account: ?Account): Array => { const a = account; if (!a) return []; - return pending.filter(p => p.network === a.network && p.address === a.address); + return pending.filter(p => p.network === a.network && p.address === a.descriptor); }; export const getPendingSequence = (pending: Array): number => pending.reduce((value: number, tx: Transaction) => { @@ -104,7 +104,7 @@ export const getPendingAmount = (pending: Array, currency: string, export const getAccountTokens = (state: State, account: ?Account): Array => { const a = account; if (!a) return []; - return state.tokens.filter(t => t.ethAddress === a.address && t.network === a.network && t.deviceState === a.deviceState); + return state.tokens.filter(t => t.ethAddress === a.descriptor && t.network === a.network && t.deviceState === a.deviceState); }; export const getWeb3 = (state: State): ?Web3Instance => { diff --git a/src/services/LocalStorageService.js b/src/services/LocalStorageService.js index 3f9775be..7719120e 100644 --- a/src/services/LocalStorageService.js +++ b/src/services/LocalStorageService.js @@ -37,8 +37,7 @@ const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: Middlewar break; case ACCOUNT.CREATE: - case ACCOUNT.SET_BALANCE: - case ACCOUNT.SET_NONCE: + case ACCOUNT.UPDATE: api.dispatch(LocalStorageActions.save()); break; diff --git a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js index 3e500e3c..202632b5 100644 --- a/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js +++ b/src/views/Wallet/components/LeftNavigation/components/AccountMenu/index.js @@ -161,10 +161,8 @@ const AccountMenu = (props: Props) => { const discovery = props.discovery.find(d => d.deviceState === selected.state && d.network === location.state.network); if (discovery && discovery.completed) { - // TODO: add only if last one is not empty - //if (selectedAccounts.length > 0 && selectedAccounts[selectedAccounts.length - 1]) const lastAccount = deviceAccounts[deviceAccounts.length - 1]; - if (lastAccount && (new BigNumber(lastAccount.balance).greaterThan(0) || lastAccount.nonce > 0)) { + if (lastAccount && !lastAccount.empty) { discoveryStatus = ( diff --git a/src/views/Wallet/views/Account/Receive/ethereum/index.js b/src/views/Wallet/views/Account/Receive/ethereum/index.js index 5646b7ed..34109886 100644 --- a/src/views/Wallet/views/Account/Receive/ethereum/index.js +++ b/src/views/Wallet/views/Account/Receive/ethereum/index.js @@ -111,9 +111,9 @@ const AccountReceive = (props: Props) => { const isAddressVerifying = props.modal.context === CONTEXT_DEVICE && props.modal.windowType === 'ButtonRequest_Address'; const isAddressHidden = !isAddressVerifying && !addressVerified && !addressUnverified; - let address = `${account.address.substring(0, 20)}...`; + let address = `${account.descriptor.substring(0, 20)}...`; if (addressVerified || addressUnverified || isAddressVerifying) { - ({ address } = account); + address = account.descriptor; } return ( @@ -149,7 +149,7 @@ const AccountReceive = (props: Props) => { /> )} > - props.showAddress(account.addressPath)}> + props.showAddress(account.accountPath)}> { )} /> {!(addressVerified || addressUnverified) && ( - props.showAddress(account.addressPath)} isDisabled={device.connected && !discovery.completed}> + props.showAddress(account.accountPath)} isDisabled={device.connected && !discovery.completed}> Show full address )} @@ -172,7 +172,7 @@ const AccountReceive = (props: Props) => { fgColor="#000000" level="Q" style={{ width: 150 }} - value={account.address} + value={account.descriptor} /> )} diff --git a/src/views/Wallet/views/Account/Receive/ripple/index.js b/src/views/Wallet/views/Account/Receive/ripple/index.js index c308eafd..e439466a 100644 --- a/src/views/Wallet/views/Account/Receive/ripple/index.js +++ b/src/views/Wallet/views/Account/Receive/ripple/index.js @@ -111,9 +111,9 @@ const AccountReceive = (props: Props) => { const isAddressVerifying = props.modal.context === CONTEXT_DEVICE && props.modal.windowType === 'ButtonRequest_Address'; const isAddressHidden = !isAddressVerifying && !addressVerified && !addressUnverified; - let address = `${account.address.substring(0, 20)}...`; + let address = `${account.descriptor.substring(0, 20)}...`; if (addressVerified || addressUnverified || isAddressVerifying) { - ({ address } = account); + address = account.descriptor; } return ( @@ -149,7 +149,7 @@ const AccountReceive = (props: Props) => { /> )} > - props.showAddress(account.addressPath)}> + props.showAddress(account.accountPath)}> { )} /> {!(addressVerified || addressUnverified) && ( - props.showAddress(account.addressPath)} isDisabled={device.connected && !discovery.completed}> + props.showAddress(account.accountPath)} isDisabled={device.connected && !discovery.completed}> Show full address )} @@ -172,7 +172,7 @@ const AccountReceive = (props: Props) => { fgColor="#000000" level="Q" style={{ width: 150 }} - value={account.address} + value={account.descriptor} /> )} diff --git a/src/views/Wallet/views/Account/SignVerify/index.js b/src/views/Wallet/views/Account/SignVerify/index.js index 100f3ce6..d1570034 100644 --- a/src/views/Wallet/views/Account/SignVerify/index.js +++ b/src/views/Wallet/views/Account/SignVerify/index.js @@ -86,7 +86,7 @@ class SignVerify extends Component { { >Clear signVerifyActions.sign(account.addressPath, signMessage)} + onClick={() => signVerifyActions.sign(account.accountPath, signMessage)} >Sign diff --git a/src/views/Wallet/views/Account/Summary/ethereum/index.js b/src/views/Wallet/views/Account/Summary/ethereum/index.js index fe9aed68..e7cc7cc2 100644 --- a/src/views/Wallet/views/Account/Summary/ethereum/index.js +++ b/src/views/Wallet/views/Account/Summary/ethereum/index.js @@ -84,7 +84,7 @@ const AccountSummary = (props: Props) => { return ; } - const explorerLink: string = `${network.explorer.address}${account.address}`; + const explorerLink: string = `${network.explorer.address}${account.descriptor}`; const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol); const balance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10); diff --git a/src/views/Wallet/views/Account/Summary/ripple/index.js b/src/views/Wallet/views/Account/Summary/ripple/index.js index fd4d4a77..260e2685 100644 --- a/src/views/Wallet/views/Account/Summary/ripple/index.js +++ b/src/views/Wallet/views/Account/Summary/ripple/index.js @@ -74,7 +74,7 @@ const AccountSummary = (props: Props) => { return ; } - const explorerLink: string = `${network.explorer.address}${account.address}`; + const explorerLink: string = `${network.explorer.address}${account.descriptor}`; const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol); const balance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10); From d9e809e6aa9d1d2c3216e827ed4e164afe213e61 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Fri, 21 Dec 2018 11:19:40 +0100 Subject: [PATCH 2/2] move helper methods from TokensReducer to ./reducers/utils --- src/actions/LocalStorageActions.js | 4 ++-- src/actions/SelectedAccountActions.js | 2 +- src/actions/SessionStorageActions.js | 2 +- src/actions/ethereum/SendFormActions.js | 5 ++--- src/actions/ethereum/SendFormValidationActions.js | 3 +-- src/reducers/TokensReducer.js | 6 ------ src/reducers/utils/index.js | 6 ++++-- 7 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/actions/LocalStorageActions.js b/src/actions/LocalStorageActions.js index fe71ea58..7742b345 100644 --- a/src/actions/LocalStorageActions.js +++ b/src/actions/LocalStorageActions.js @@ -12,7 +12,7 @@ import { httpRequest } from 'utils/networkUtils'; import * as buildUtils from 'utils/build'; import * as storageUtils from 'utils/storage'; -import { findAccountTokens } from 'reducers/TokensReducer'; +import { getAccountTokens } from 'reducers/utils'; import type { Account } from 'reducers/AccountsReducer'; import type { Token } from 'reducers/TokensReducer'; import type { Discovery } from 'reducers/DiscoveryReducer'; @@ -59,7 +59,7 @@ const KEY_BETA_MODAL: string = '/betaModalPrivacy'; // this key needs to be comp const findAccounts = (devices: Array, accounts: Array): Array => devices.reduce((arr, dev) => arr.concat(accounts.filter(a => a.deviceState === dev.state)), []); -const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(findAccountTokens(tokens, account)), []); +const findTokens = (accounts: Array, tokens: Array): Array => accounts.reduce((arr, account) => arr.concat(getAccountTokens(tokens, account)), []); const findDiscovery = (devices: Array, discovery: Array): Array => devices.reduce((arr, dev) => arr.concat(discovery.filter(d => d.deviceState === dev.state && d.completed)), []); diff --git a/src/actions/SelectedAccountActions.js b/src/actions/SelectedAccountActions.js index fe6a0d2e..ba498cf0 100644 --- a/src/actions/SelectedAccountActions.js +++ b/src/actions/SelectedAccountActions.js @@ -210,7 +210,7 @@ export const observe = (prevState: State, action: Action): PayloadAction async (dispatch: Dispatch, getState: Ge const txData = await dispatch(prepareEthereumTx({ network: network.shortcut, - token: isToken ? findToken(getState().tokens, account.descriptor, currentState.currency, account.deviceState) : null, + token: isToken ? reducerUtils.findToken(getState().tokens, account.descriptor, currentState.currency, account.deviceState) : null, from: account.descriptor, to: currentState.address, amount: currentState.amount, diff --git a/src/actions/ethereum/SendFormValidationActions.js b/src/actions/ethereum/SendFormValidationActions.js index 1720ce23..46451fb5 100644 --- a/src/actions/ethereum/SendFormValidationActions.js +++ b/src/actions/ethereum/SendFormValidationActions.js @@ -3,8 +3,7 @@ import BigNumber from 'bignumber.js'; import EthereumjsUtil from 'ethereumjs-util'; import EthereumjsUnits from 'ethereumjs-units'; -import { findToken } from 'reducers/TokensReducer'; -import { findDevice, getPendingAmount } from 'reducers/utils'; +import { findDevice, getPendingAmount, findToken } from 'reducers/utils'; import * as SEND from 'actions/constants/send'; import * as ethUtils from 'utils/ethUtils'; diff --git a/src/reducers/TokensReducer.js b/src/reducers/TokensReducer.js index 847a7bbd..f9d00f12 100644 --- a/src/reducers/TokensReducer.js +++ b/src/reducers/TokensReducer.js @@ -6,7 +6,6 @@ import * as WALLET from 'actions/constants/wallet'; import * as TOKEN from 'actions/constants/token'; import type { Action, TrezorDevice } from 'flowtype'; -import type { Account } from './AccountsReducer'; export type Token = { loaded: boolean; @@ -24,11 +23,6 @@ export type State = Array; const initialState: State = []; -// Helper for actions -export const findToken = (state: Array, address: string, symbol: string, deviceState: string): ?Token => state.find(t => t.ethAddress === address && t.symbol === symbol && t.deviceState === deviceState); - -export const findAccountTokens = (state: Array, account: Account): Array => state.filter(t => t.ethAddress === account.descriptor && t.network === account.network && t.deviceState === account.deviceState); - const create = (state: State, token: Token): State => { const newState: State = [...state]; newState.push(token); diff --git a/src/reducers/utils/index.js b/src/reducers/utils/index.js index d01e6568..7104ca8e 100644 --- a/src/reducers/utils/index.js +++ b/src/reducers/utils/index.js @@ -101,10 +101,12 @@ export const getPendingAmount = (pending: Array, currency: string, return value; }, new BigNumber('0')); -export const getAccountTokens = (state: State, account: ?Account): Array => { +export const findToken = (state: Array, address: string, symbol: string, deviceState: string): ?Token => state.find(t => t.ethAddress === address && t.symbol === symbol && t.deviceState === deviceState); + +export const getAccountTokens = (tokens: Array, account: ?Account): Array => { const a = account; if (!a) return []; - return state.tokens.filter(t => t.ethAddress === a.descriptor && t.network === a.network && t.deviceState === a.deviceState); + return tokens.filter(t => t.ethAddress === a.descriptor && t.network === a.network && t.deviceState === a.deviceState); }; export const getWeb3 = (state: State): ?Web3Instance => {