import React from 'react'; import { connect } from 'react-redux'; import BN from 'bn.js'; import translate from 'translations'; import { IWallet } from 'libs/wallet'; import { validPositiveNumber, validDecimal } from 'libs/validators'; import { buildEIP681EtherRequest, buildEIP681TokenRequest } from 'libs/values'; import { ICurrentTo, ICurrentValue } from 'features/types'; import { AppState } from 'features/reducers'; import * as derivedSelectors from 'features/selectors'; import { getNetworkConfig, isNetworkUnit } from 'features/config'; import { transactionFieldsTypes, transactionFieldsActions, transactionFieldsSelectors, transactionMetaSelectors, transactionActions } from 'features/transaction'; import { AddressField, AmountField, TXMetaDataPanel } from 'components'; import { QRCode, CodeBlock } from 'components/ui'; import { NetworkConfig } from 'types/network'; import './RequestPayment.scss'; interface OwnProps { wallet: AppState['wallet']['inst']; } interface StateProps { unit: string; currentTo: ICurrentTo; currentValue: ICurrentValue; gasLimit: transactionFieldsTypes.SetGasLimitFieldAction['payload']; networkConfig: NetworkConfig; decimal: number; tokenContractAddress: string; isNetworkUnit: boolean; } interface ActionProps { resetTransactionRequested: transactionFieldsActions.TResetTransactionRequested; setCurrentTo: transactionActions.TSetCurrentTo; } type Props = OwnProps & StateProps & ActionProps; const isValidAmount = (decimal: number) => (amount: string) => validPositiveNumber(+amount) && validDecimal(amount, decimal); class RequestPayment extends React.Component { public state = { recipientAddress: '' }; public componentDidMount() { this.props.resetTransactionRequested(); if (this.props.wallet) { this.setWalletAsyncState(this.props.wallet); } } public componentWillUnmount() { this.props.resetTransactionRequested(); } public UNSAFE_componentWillReceiveProps(nextProps: Props) { if (nextProps.wallet && this.props.wallet !== nextProps.wallet) { this.setWalletAsyncState(nextProps.wallet); } } public render() { const { tokenContractAddress, gasLimit, currentTo, currentValue, networkConfig, unit, decimal } = this.props; const chainId = networkConfig ? networkConfig.chainId : undefined; const eip681String = this.generateEIP681String( currentTo.raw, tokenContractAddress, currentValue, gasLimit, unit, decimal, chainId ); return (
{!!eip681String.length && (
{eip681String}
)}
); } private setWalletAsyncState(wallet: IWallet) { this.props.setCurrentTo(wallet.getAddressString()); } private generateEIP681String( currentTo: string, tokenContractAddress: string, currentValue: { raw: string; value: BN | null }, gasLimit: { raw: string; value: BN | null }, unit: string, decimal: number, chainId?: number ) { if ( !isValidAmount(decimal)(currentValue.raw) || !chainId || !gasLimit || !gasLimit.raw.length || !currentTo.length || (unit !== 'ETH' && !tokenContractAddress.length) ) { return ''; } const currentValueIsEther = ( _: AppState['transaction']['fields']['value'] | AppState['transaction']['meta']['tokenTo'] ): _ is AppState['transaction']['fields']['value'] => this.props.isNetworkUnit; if (currentValueIsEther(currentValue)) { return buildEIP681EtherRequest(currentTo, chainId, currentValue); } else { return buildEIP681TokenRequest( currentTo, tokenContractAddress, chainId, currentValue, decimal, gasLimit ); } } } function mapStateToProps(state: AppState): StateProps { return { unit: derivedSelectors.getUnit(state), currentTo: derivedSelectors.getCurrentTo(state), currentValue: derivedSelectors.getCurrentValue(state), gasLimit: transactionFieldsSelectors.getGasLimit(state), networkConfig: getNetworkConfig(state), decimal: transactionMetaSelectors.getDecimal(state), tokenContractAddress: derivedSelectors.getSelectedTokenContractAddress(state), isNetworkUnit: isNetworkUnit(state, derivedSelectors.getUnit(state)) }; } export default connect(mapStateToProps, { resetTransactionRequested: transactionFieldsActions.resetTransactionRequested, setCurrentTo: transactionActions.setCurrentTo })(RequestPayment);