2018-01-03 03:18:10 +00:00
|
|
|
import React from 'react';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { AppState } from 'reducers';
|
|
|
|
import translate from 'translations';
|
|
|
|
import { IWallet } from 'libs/wallet';
|
|
|
|
import { QRCode } from 'components/ui';
|
|
|
|
import { getUnit, getDecimal } from 'selectors/transaction/meta';
|
|
|
|
import {
|
|
|
|
getCurrentTo,
|
|
|
|
getCurrentValue,
|
|
|
|
ICurrentTo,
|
|
|
|
ICurrentValue
|
|
|
|
} from 'selectors/transaction/current';
|
|
|
|
import BN from 'bn.js';
|
|
|
|
import { validNumber, validDecimal } from 'libs/validators';
|
|
|
|
import { getGasLimit } from 'selectors/transaction';
|
2018-01-25 03:43:27 +00:00
|
|
|
import { AddressField, AmountField, TXMetaDataPanel } from 'components';
|
2018-01-03 03:18:10 +00:00
|
|
|
import { SetGasLimitFieldAction } from 'actions/transaction/actionTypes/fields';
|
|
|
|
import { buildEIP681EtherRequest, buildEIP681TokenRequest } from 'libs/values';
|
|
|
|
import { getNetworkConfig, getSelectedTokenContractAddress } from 'selectors/config';
|
|
|
|
import './RequestPayment.scss';
|
|
|
|
import { reset, TReset, setCurrentTo, TSetCurrentTo } from 'actions/transaction';
|
2018-02-12 20:43:07 +00:00
|
|
|
import { NetworkConfig } from 'types/network';
|
2018-01-03 03:18:10 +00:00
|
|
|
|
|
|
|
interface OwnProps {
|
|
|
|
wallet: AppState['wallet']['inst'];
|
|
|
|
}
|
|
|
|
|
|
|
|
interface StateProps {
|
|
|
|
unit: string;
|
|
|
|
currentTo: ICurrentTo;
|
|
|
|
currentValue: ICurrentValue;
|
|
|
|
gasLimit: SetGasLimitFieldAction['payload'];
|
2018-02-12 20:43:07 +00:00
|
|
|
networkConfig: NetworkConfig;
|
2018-01-03 03:18:10 +00:00
|
|
|
decimal: number;
|
|
|
|
tokenContractAddress: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface ActionProps {
|
|
|
|
reset: TReset;
|
|
|
|
setCurrentTo: TSetCurrentTo;
|
|
|
|
}
|
|
|
|
|
|
|
|
type Props = OwnProps & StateProps & ActionProps;
|
|
|
|
|
|
|
|
const isValidAmount = decimal => amount => validNumber(+amount) && validDecimal(amount, decimal);
|
|
|
|
|
|
|
|
class RequestPayment extends React.Component<Props, {}> {
|
|
|
|
public state = {
|
|
|
|
recipientAddress: ''
|
|
|
|
};
|
|
|
|
|
|
|
|
public componentDidMount() {
|
|
|
|
if (this.props.wallet) {
|
|
|
|
this.setWalletAsyncState(this.props.wallet);
|
|
|
|
}
|
|
|
|
this.props.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
public componentWillUnmount() {
|
|
|
|
this.props.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
public 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 (
|
|
|
|
<div className="RequestPayment">
|
|
|
|
<div className="Tab-content-pane">
|
|
|
|
<AddressField isReadOnly={true} />
|
|
|
|
|
|
|
|
<div className="row form-group">
|
|
|
|
<div className="col-xs-11">
|
|
|
|
<AmountField
|
|
|
|
hasUnitDropdown={true}
|
|
|
|
showAllTokens={true}
|
|
|
|
customValidator={isValidAmount(decimal)}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="row form-group">
|
|
|
|
<div className="col-xs-11">
|
2018-01-25 03:43:27 +00:00
|
|
|
<TXMetaDataPanel
|
|
|
|
initialState="advanced"
|
|
|
|
disableToggle={true}
|
|
|
|
advancedGasOptions={{
|
|
|
|
gasPriceField: false,
|
|
|
|
nonceField: false,
|
|
|
|
dataField: false,
|
|
|
|
feeSummary: false
|
|
|
|
}}
|
|
|
|
/>
|
2018-01-03 03:18:10 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{!!eip681String.length && (
|
|
|
|
<div className="row form-group">
|
|
|
|
<div className="col-xs-6">
|
|
|
|
<label>{translate('Payment QR & Code')}</label>
|
|
|
|
<div className="RequestPayment-qr well well-lg">
|
|
|
|
<QRCode data={eip681String} />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="col-xs-6 RequestPayment-codeContainer">
|
|
|
|
<textarea
|
|
|
|
className="RequestPayment-codeBox form-control"
|
|
|
|
value={eip681String}
|
|
|
|
disabled={true}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-02-21 18:23:04 +00:00
|
|
|
private setWalletAsyncState(wallet: IWallet) {
|
|
|
|
this.props.setCurrentTo(wallet.getAddressString());
|
2018-01-03 03:18:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private generateEIP681String(
|
|
|
|
currentTo: string,
|
|
|
|
tokenContractAddress: string,
|
|
|
|
currentValue,
|
|
|
|
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 !== 'ether' && !tokenContractAddress.length)
|
|
|
|
) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (unit === 'ether') {
|
|
|
|
return buildEIP681EtherRequest(currentTo, chainId, currentValue);
|
|
|
|
} else {
|
|
|
|
return buildEIP681TokenRequest(
|
|
|
|
currentTo,
|
|
|
|
tokenContractAddress,
|
|
|
|
chainId,
|
|
|
|
currentValue,
|
|
|
|
decimal,
|
|
|
|
gasLimit
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapStateToProps(state: AppState): StateProps {
|
|
|
|
return {
|
|
|
|
unit: getUnit(state),
|
|
|
|
currentTo: getCurrentTo(state),
|
|
|
|
currentValue: getCurrentValue(state),
|
|
|
|
gasLimit: getGasLimit(state),
|
|
|
|
networkConfig: getNetworkConfig(state),
|
|
|
|
decimal: getDecimal(state),
|
|
|
|
tokenContractAddress: getSelectedTokenContractAddress(state)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(mapStateToProps, { reset, setCurrentTo })(RequestPayment);
|