mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-24 01:08:27 +00:00
Account balance - pending txs
This commit is contained in:
parent
43ddffb6e9
commit
00ee6465c9
@ -36,6 +36,7 @@ export const updateSelectedValues = (prevState: State, action: Action): AsyncAct
|
||||
const locationChange: boolean = action.type === LOCATION_CHANGE;
|
||||
const state: State = getState();
|
||||
const location = state.router.location;
|
||||
const prevLocation = prevState.router.location;
|
||||
|
||||
let needUpdate: boolean = false;
|
||||
|
||||
@ -51,13 +52,14 @@ export const updateSelectedValues = (prevState: State, action: Action): AsyncAct
|
||||
|| prevState.accounts !== state.accounts
|
||||
|| prevState.discovery !== state.discovery
|
||||
|| prevState.tokens !== state.tokens
|
||||
|| prevState.pending !== state.pending
|
||||
|| prevState.web3 !== state.web3) {
|
||||
|
||||
const account = stateUtils.getSelectedAccount(state);
|
||||
const network = stateUtils.getSelectedNetwork(state);
|
||||
const discovery = stateUtils.getDiscoveryProcess(state);
|
||||
const tokens = stateUtils.getAccountTokens(state, account);
|
||||
const pending = stateUtils.getAccountPendingTx(state, account);
|
||||
const pending = stateUtils.getAccountPendingTx(state.pending, account);
|
||||
const web3 = stateUtils.getWeb3(state);
|
||||
|
||||
const payload: $ElementType<State, 'selectedAccount'> = {
|
||||
@ -81,13 +83,17 @@ export const updateSelectedValues = (prevState: State, action: Action): AsyncAct
|
||||
dispatch({
|
||||
type: ACCOUNT.UPDATE_SELECTED_ACCOUNT,
|
||||
payload,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (locationChange) {
|
||||
|
||||
if (prevState.router.location && prevState.router.location.state.send) {
|
||||
SessionStorageActions.save(prevState.router.location.pathname, state.sendForm);
|
||||
if (prevLocation) {
|
||||
// save form data to session storage
|
||||
// TODO: move to state.sendForm on change event
|
||||
if (prevLocation.state.send) {
|
||||
SessionStorageActions.save(prevState.router.location.pathname, state.sendForm);
|
||||
}
|
||||
}
|
||||
|
||||
dispatch( dispose() );
|
||||
|
@ -18,8 +18,10 @@ import { initialState } from '../reducers/SendFormReducer';
|
||||
import { findAccount } from '../reducers/AccountsReducer';
|
||||
import { findToken } from '../reducers/TokensReducer';
|
||||
import { findDevice } from '../reducers/utils';
|
||||
import * as stateUtils from '../reducers/utils';
|
||||
|
||||
import type {
|
||||
PendingTx,
|
||||
Dispatch,
|
||||
GetState,
|
||||
Action,
|
||||
@ -41,6 +43,8 @@ export type SendTxAction = {
|
||||
account: Account,
|
||||
selectedCurrency: string,
|
||||
amount: string,
|
||||
total: string,
|
||||
tx: any,
|
||||
txid: string,
|
||||
txData: any,
|
||||
};
|
||||
@ -156,8 +160,6 @@ export const calculate = (prevProps: Props, props: Props) => {
|
||||
} = props.selectedAccount;
|
||||
if (!account) return;
|
||||
|
||||
console.warn("CALCULATE!", props)
|
||||
|
||||
const prevState = prevProps.sendForm;
|
||||
const state = props.sendForm;
|
||||
const isToken: boolean = state.currency !== state.networkSymbol;
|
||||
@ -173,18 +175,16 @@ export const calculate = (prevProps: Props, props: Props) => {
|
||||
|
||||
if (state.setMax) {
|
||||
|
||||
const pendingAmount = pending.reduce((value, p) => {
|
||||
//if (p.tx.amount)
|
||||
console.warn("PENDING AMOUNT!", p, value);
|
||||
}, 0);
|
||||
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, state.currency);
|
||||
|
||||
if (isToken) {
|
||||
const token: ?Token = findToken(tokens, account.address, state.currency, account.deviceState);
|
||||
if (token) {
|
||||
state.amount = token.balance;
|
||||
state.amount = new BigNumber(token.balance).minus(pendingAmount).toString();
|
||||
}
|
||||
} else {
|
||||
state.amount = calculateMaxAmount(account.balance, state.gasPrice, state.gasLimit);
|
||||
const b = new BigNumber(account.balance).minus(pendingAmount).toString();
|
||||
state.amount = calculateMaxAmount(b, state.gasPrice, state.gasLimit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,6 +350,7 @@ export const validation = (props: Props): void => {
|
||||
account,
|
||||
network,
|
||||
tokens,
|
||||
pending,
|
||||
} = props.selectedAccount;
|
||||
if (!account || !network) return;
|
||||
|
||||
@ -389,6 +390,7 @@ export const validation = (props: Props): void => {
|
||||
} else {
|
||||
|
||||
let decimalRegExp: RegExp;
|
||||
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, state.currency);
|
||||
|
||||
if (state.currency !== state.networkSymbol) {
|
||||
const token = findToken(tokens, account.address, state.currency, account.deviceState);
|
||||
@ -405,7 +407,7 @@ export const validation = (props: Props): void => {
|
||||
errors.amount = `Maximum ${ token.decimals} decimals allowed`;
|
||||
} else if (new BigNumber(state.total).greaterThan(account.balance)) {
|
||||
errors.amount = `Not enough ${ state.networkSymbol } to cover transaction fee`;
|
||||
} else if (new BigNumber(state.amount).greaterThan(token.balance)) {
|
||||
} else if (new BigNumber(state.amount).greaterThan( new BigNumber(token.balance).minus(pendingAmount) )) {
|
||||
errors.amount = 'Not enough funds';
|
||||
} else if (new BigNumber(state.amount).lessThanOrEqualTo('0')) {
|
||||
errors.amount = 'Amount is too low';
|
||||
@ -416,7 +418,7 @@ export const validation = (props: Props): void => {
|
||||
decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9][0-9]*\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$');
|
||||
if (!state.amount.match(decimalRegExp)) {
|
||||
errors.amount = `Maximum 18 decimals allowed`;
|
||||
} else if (new BigNumber(state.total).greaterThan(account.balance)) {
|
||||
} else if (new BigNumber(state.total).greaterThan( new BigNumber(account.balance).minus(pendingAmount) )) {
|
||||
errors.amount = 'Not enough funds';
|
||||
}
|
||||
}
|
||||
@ -916,6 +918,8 @@ export const onSend = (): AsyncAction => {
|
||||
account: account,
|
||||
selectedCurrency: currentState.currency,
|
||||
amount: currentState.amount,
|
||||
total: currentState.total,
|
||||
tx,
|
||||
txid,
|
||||
txData,
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ const PendingTransactions = (props: Props) => {
|
||||
const bgColorFactory = new ColorHash({lightness: 0.7});
|
||||
const textColorFactory = new ColorHash();
|
||||
|
||||
const pendingTxs = pending.map((tx, i) => {
|
||||
const pendingTxs: React$Element<string> = pending.map((tx, i) => {
|
||||
|
||||
let iconColor: Style;
|
||||
let symbol: string;
|
||||
@ -80,7 +80,7 @@ const PendingTransactions = (props: Props) => {
|
||||
<div className="name">
|
||||
<a href={ `${props.network.explorer.tx}${tx.id}`} target="_blank" rel="noreferrer noopener">{ name }</a>
|
||||
</div>
|
||||
<div className="amount">{ tx.amount } { symbol }</div>
|
||||
<div className="amount">{ tx.total } { symbol }</div>
|
||||
</div>
|
||||
)
|
||||
});
|
||||
|
@ -11,6 +11,7 @@ import SelectedAccount from '../SelectedAccount';
|
||||
import { Notification } from '~/js/components/common/Notification';
|
||||
import SummaryDetails from './SummaryDetails.js';
|
||||
import SummaryTokens from './SummaryTokens.js';
|
||||
import * as stateUtils from '~/js/reducers/utils';
|
||||
|
||||
import type { Props } from './index';
|
||||
import type { NetworkToken } from '~/js/reducers/LocalStorageReducer';
|
||||
@ -21,6 +22,7 @@ const Summary = (props: Props) => {
|
||||
account,
|
||||
network,
|
||||
tokens,
|
||||
pending
|
||||
} = props.selectedAccount;
|
||||
|
||||
// flow
|
||||
@ -33,6 +35,9 @@ const Summary = (props: Props) => {
|
||||
);
|
||||
const explorerLink: string = `${network.explorer.address}${account.address}`;
|
||||
|
||||
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol);
|
||||
const balance: string = new BigNumber(account.balance).minus(pendingAmount).toString();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h2 className={ `summary-header ${account.network}` }>
|
||||
@ -43,7 +48,7 @@ const Summary = (props: Props) => {
|
||||
<SummaryDetails
|
||||
coin={ network }
|
||||
summary={ props.summary }
|
||||
balance={ account.balance }
|
||||
balance={ balance }
|
||||
network={ network.network }
|
||||
fiat={ props.fiat }
|
||||
localStorage={ props.localStorage }
|
||||
|
@ -6,6 +6,7 @@ import { Link, NavLink } from 'react-router-dom';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import { findDeviceAccounts } from '~/js/reducers/AccountsReducer';
|
||||
import * as stateUtils from '~/js/reducers/utils';
|
||||
import Loader from '~/js/components/common/LoaderCircle';
|
||||
import Tooltip from 'rc-tooltip';
|
||||
|
||||
@ -36,12 +37,16 @@ const AccountSelection = (props: Props): ?React$Element<string> => {
|
||||
|
||||
let balance: string = 'Loading...';
|
||||
if (account.balance !== '') {
|
||||
const pending = stateUtils.getAccountPendingTx(props.pending, account);
|
||||
const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, selectedCoin.symbol);
|
||||
const availableBalance: string = new BigNumber(account.balance).minus(pendingAmount).toString();
|
||||
|
||||
if (fiatRate) {
|
||||
const accountBalance = new BigNumber(account.balance);
|
||||
const accountBalance = new BigNumber(availableBalance);
|
||||
const fiat = accountBalance.times(fiatRate.value).toFixed(2);
|
||||
balance = `${ account.balance } ${ selectedCoin.symbol } / $${ fiat }`;
|
||||
balance = `${ availableBalance } ${ selectedCoin.symbol } / $${ fiat }`;
|
||||
} else {
|
||||
balance = `${ account.balance } ${ selectedCoin.symbol }`;
|
||||
balance = `${ availableBalance } ${ selectedCoin.symbol }`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ type StateProps = {
|
||||
discovery: $ElementType<State, 'discovery'>,
|
||||
wallet: $ElementType<State, 'wallet'>,
|
||||
devices: $ElementType<State, 'devices'>,
|
||||
pending: $ElementType<State, 'pending'>,
|
||||
}
|
||||
|
||||
type DispatchProps = {
|
||||
@ -52,7 +53,8 @@ const mapStateToProps: MapStateToProps<State, OwnProps, StateProps> = (state: St
|
||||
localStorage: state.localStorage,
|
||||
discovery: state.discovery,
|
||||
wallet: state.wallet,
|
||||
devices: state.devices
|
||||
devices: state.devices,
|
||||
pending: state.pending,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ export type PendingTx = {
|
||||
+network: string;
|
||||
+currency: string;
|
||||
+amount: string;
|
||||
+total: string;
|
||||
+tx: any;
|
||||
+address: string;
|
||||
}
|
||||
|
||||
@ -27,6 +29,8 @@ const add = (state: State, action: SendTxAction): State => {
|
||||
network: action.account.network,
|
||||
currency: action.selectedCurrency,
|
||||
amount: action.amount,
|
||||
total: action.total,
|
||||
tx: action.tx,
|
||||
address: action.account.address,
|
||||
});
|
||||
return newState;
|
||||
|
@ -4,6 +4,7 @@
|
||||
import * as LogActions from '~/js/actions/LogActions';
|
||||
import * as STORAGE from '~/js/actions/constants/localStorage';
|
||||
import * as WALLET from '~/js/actions/constants/wallet';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import type {
|
||||
Middleware,
|
||||
@ -84,15 +85,24 @@ export const getDiscoveryProcess = (state: State): ?Discovery => {
|
||||
return state.discovery.find(d => d.deviceState === device.state && d.network === locationState.network);
|
||||
}
|
||||
|
||||
export const getAccountPendingTx = (state: State, account: ?Account): Array<PendingTx> => {
|
||||
export const getAccountPendingTx = (pending: Array<PendingTx>, account: ?Account): Array<PendingTx> => {
|
||||
const a = account;
|
||||
if (!a) return state.selectedAccount.pending.length > 0 ? [] : state.selectedAccount.pending;
|
||||
return state.pending.filter(p => p.network === a.network && p.address === a.address);
|
||||
if (!a) return [];
|
||||
return pending.filter(p => p.network === a.network && p.address === a.address);
|
||||
}
|
||||
|
||||
export const getPendingAmount = (pending: Array<PendingTx>, currency: string): BigNumber => {
|
||||
return pending.reduce((value: BigNumber, tx: PendingTx) => {
|
||||
if (tx.currency === currency) {
|
||||
return new BigNumber(value).plus(tx.amount);
|
||||
}
|
||||
return value;
|
||||
}, new BigNumber('0'));
|
||||
}
|
||||
|
||||
export const getAccountTokens = (state: State, account: ?Account): Array<Token> => {
|
||||
const a = account;
|
||||
if (!a) return state.selectedAccount.tokens.length > 0 ? [] : state.selectedAccount.tokens;
|
||||
if (!a) return [];
|
||||
return state.tokens.filter(t => t.ethAddress === a.address && t.network === a.network && t.deviceState === a.deviceState);
|
||||
}
|
||||
|
||||
@ -100,4 +110,5 @@ export const getWeb3 = (state: State): ?Web3Instance => {
|
||||
const locationState = state.router.location.state;
|
||||
if (!locationState.network) return null;
|
||||
return state.web3.find(w3 => w3.network === locationState.network);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user