[FEATURE] Redirection to the DApp for details.
This commit is contained in:
parent
e3884fc5ae
commit
9a70d776b4
|
@ -4,7 +4,7 @@ import { withRouter, Switch, Redirect, HashRouter, Route, BrowserRouter } from '
|
|||
// Components
|
||||
import Contracts from 'containers/Tabs/Contracts';
|
||||
import ENS from 'containers/Tabs/ENS';
|
||||
import Schedule from 'containers/Tabs/Schedule';
|
||||
import ScheduleTransaction from 'containers/Tabs/ScheduleTransaction';
|
||||
import GenerateWallet from 'containers/Tabs/GenerateWallet';
|
||||
import SendTransaction from 'containers/Tabs/SendTransaction';
|
||||
import Swap from 'containers/Tabs/Swap';
|
||||
|
@ -82,7 +82,7 @@ class RootClass extends Component<Props, State> {
|
|||
<Route path="/swap" component={Swap} />
|
||||
<Route path="/contracts" component={Contracts} />
|
||||
<Route path="/ens" component={ENS} exact={true} />
|
||||
<Route path="/schedule" component={Schedule} exact={true} />
|
||||
<Route path="/schedule" component={ScheduleTransaction} exact={true} />
|
||||
<Route path="/sign-and-verify-message" component={SignAndVerifyMessage} />
|
||||
<Route path="/tx-status" component={CheckTransaction} exact={true} />
|
||||
<Route path="/pushTx" component={BroadcastTx} />
|
||||
|
|
|
@ -3,13 +3,15 @@ import { Link } from 'react-router-dom';
|
|||
import translate from 'translations';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { BlockExplorerConfig } from 'types/network';
|
||||
import { getTXDetailsCheckURL } from 'libs/scheduling';
|
||||
|
||||
export interface TransactionSucceededProps {
|
||||
txHash: string;
|
||||
blockExplorer?: BlockExplorerConfig;
|
||||
scheduling?: boolean;
|
||||
}
|
||||
|
||||
const TransactionSucceeded = ({ txHash, blockExplorer }: TransactionSucceededProps) => {
|
||||
const TransactionSucceeded = ({ txHash, blockExplorer, scheduling }: TransactionSucceededProps) => {
|
||||
let verifyBtn: React.ReactElement<string> | undefined;
|
||||
if (blockExplorer) {
|
||||
verifyBtn = (
|
||||
|
@ -19,11 +21,21 @@ const TransactionSucceeded = ({ txHash, blockExplorer }: TransactionSucceededPro
|
|||
);
|
||||
}
|
||||
|
||||
let scheduleDetailsBtn: React.ReactElement<string> | undefined;
|
||||
if (scheduling) {
|
||||
scheduleDetailsBtn = (
|
||||
<a href={getTXDetailsCheckURL(txHash)} className="btn btn-xs">
|
||||
{translate('SCHEDULE_check')}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>
|
||||
{translate('SUCCESS_3')} {txHash}
|
||||
</p>
|
||||
{scheduleDetailsBtn}
|
||||
{verifyBtn}
|
||||
<Link to={`/tx-status?txHash=${txHash}`} className="btn btn-xs">
|
||||
{translate('NAV_CHECKTXSTATUS')}
|
||||
|
|
|
@ -1,25 +1,8 @@
|
|||
import { GenerateTransactionFactory } from './GenerateTransactionFactory';
|
||||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
import { ScheduleTransactionFactory } from './ScheduleTransactionFactory';
|
||||
|
||||
interface Props {
|
||||
scheduling?: boolean;
|
||||
}
|
||||
|
||||
export const GenerateTransaction: React.SFC<Props> = props => {
|
||||
if (props.scheduling) {
|
||||
return (
|
||||
<ScheduleTransactionFactory
|
||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const GenerateTransaction: React.SFC<{}> = () => {
|
||||
return (
|
||||
<GenerateTransactionFactory
|
||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||
|
|
|
@ -42,7 +42,7 @@ interface OwnProps {
|
|||
|
||||
type Props = OwnProps & StateProps;
|
||||
|
||||
class GenerateTransactionFactoryClass extends Component<Props> {
|
||||
export class GenerateTransactionFactoryClass extends Component<Props> {
|
||||
public render() {
|
||||
const {
|
||||
walletType,
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import { signTransactionRequested, TSignTransactionRequested } from 'actions/transaction';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
interface DispatchProps {
|
||||
signTransactionRequested: TSignTransactionRequested;
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
isWeb3: boolean;
|
||||
withSigner(signer: TSignTransactionRequested): React.ReactElement<any> | null;
|
||||
}
|
||||
|
||||
class Container extends Component<DispatchProps & OwnProps, {}> {
|
||||
public render() {
|
||||
return this.props.withSigner(this.props.signTransactionRequested);
|
||||
}
|
||||
}
|
||||
|
||||
export const WithSigner = connect(null, { signTransactionRequested })(Container);
|
|
@ -1,88 +0,0 @@
|
|||
import { WithSigner } from './Container';
|
||||
import EthTx from 'ethereumjs-tx';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import {
|
||||
getSchedulingTransaction,
|
||||
isNetworkRequestPending,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit,
|
||||
getGasPrice,
|
||||
getCurrentTo,
|
||||
getCurrentValue
|
||||
} from 'selectors/transaction';
|
||||
import { getWalletType } from 'selectors/wallet';
|
||||
import { getWindowStart } from '../../selectors/transaction/fields';
|
||||
|
||||
export interface CallbackProps {
|
||||
disabled: boolean;
|
||||
isWeb3Wallet: boolean;
|
||||
onClick(): void;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
transaction: EthTx;
|
||||
networkRequestPending: boolean;
|
||||
isFullTransaction: boolean;
|
||||
isWeb3Wallet: boolean;
|
||||
validGasPrice: boolean;
|
||||
validGasLimit: boolean;
|
||||
isWindowStartValid: boolean;
|
||||
windowStart: any;
|
||||
gasPrice: any;
|
||||
currentTo: any;
|
||||
currentValue: any;
|
||||
}
|
||||
|
||||
interface OwnProps {
|
||||
withProps(props: CallbackProps): React.ReactElement<any> | null;
|
||||
}
|
||||
|
||||
type Props = OwnProps & StateProps;
|
||||
|
||||
class ScheduleTransactionFactoryClass extends Component<Props> {
|
||||
public render() {
|
||||
const {
|
||||
isFullTransaction,
|
||||
isWeb3Wallet,
|
||||
networkRequestPending,
|
||||
validGasPrice,
|
||||
validGasLimit,
|
||||
isWindowStartValid,
|
||||
transaction
|
||||
} = this.props;
|
||||
|
||||
const isButtonDisabled =
|
||||
!isWindowStartValid ||
|
||||
!isFullTransaction ||
|
||||
networkRequestPending ||
|
||||
!validGasPrice ||
|
||||
!validGasLimit;
|
||||
|
||||
return (
|
||||
<WithSigner
|
||||
isWeb3={isWeb3Wallet}
|
||||
withSigner={signer =>
|
||||
this.props.withProps({
|
||||
disabled: isButtonDisabled,
|
||||
isWeb3Wallet,
|
||||
onClick: () => signer(transaction)
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ScheduleTransactionFactory = connect((state: AppState) => ({
|
||||
...getSchedulingTransaction(state),
|
||||
networkRequestPending: isNetworkRequestPending(state),
|
||||
isWeb3Wallet: getWalletType(state).isWeb3Wallet,
|
||||
validGasPrice: isValidGasPrice(state),
|
||||
validGasLimit: isValidGasLimit(state),
|
||||
windowStart: getWindowStart(state),
|
||||
gasPrice: getGasPrice(state),
|
||||
currentTo: getCurrentTo(state),
|
||||
currentValue: getCurrentValue(state)
|
||||
}))(ScheduleTransactionFactoryClass);
|
|
@ -1 +0,0 @@
|
|||
export * from './ScheduleTransactionFactory';
|
|
@ -41,7 +41,7 @@ interface OwnProps {
|
|||
|
||||
type Props = StateProps & OwnProps;
|
||||
|
||||
class SendButtonFactoryClass extends Component<Props> {
|
||||
export class SendButtonFactoryClass extends Component<Props> {
|
||||
public render() {
|
||||
const {
|
||||
signing,
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
import { ScheduleTransactionFactory } from './ScheduleTransactionFactory';
|
||||
|
||||
export const GenerateScheduleTransactionButton: React.SFC<{}> = () => {
|
||||
return (
|
||||
<ScheduleTransactionFactory
|
||||
withProps={({ disabled, isWeb3Wallet, onClick }) => (
|
||||
<button disabled={disabled} className="btn btn-info btn-block" onClick={onClick}>
|
||||
{isWeb3Wallet ? translate('SCHEDULE_schedule') : translate('DEP_signtx')}
|
||||
</button>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import {
|
||||
getSchedulingTransaction,
|
||||
isNetworkRequestPending,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit,
|
||||
getSerializedTransaction,
|
||||
getSignedTx
|
||||
} from 'selectors/transaction';
|
||||
import { getWalletType } from 'selectors/wallet';
|
||||
import { GenerateTransactionFactoryClass } from 'components/GenerateTransactionFactory';
|
||||
|
||||
export const ScheduleTransactionFactory = connect((state: AppState) => ({
|
||||
...getSchedulingTransaction(state),
|
||||
walletType: getWalletType(state),
|
||||
serializedTransaction: getSerializedTransaction(state),
|
||||
networkRequestPending: isNetworkRequestPending(state),
|
||||
isWeb3Wallet: getWalletType(state).isWeb3Wallet,
|
||||
validGasPrice: isValidGasPrice(state),
|
||||
validGasLimit: isValidGasLimit(state),
|
||||
signedTx: !!getSignedTx(state)
|
||||
}))(GenerateTransactionFactoryClass);
|
|
@ -0,0 +1,32 @@
|
|||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
import { ConfirmationModal } from 'components/ConfirmationModal';
|
||||
import { SigningStatus } from 'components';
|
||||
import { SendScheduleTransactionButtonFactory } from 'containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButtonFactory';
|
||||
|
||||
export const SendScheduleTransactionButton: React.SFC<{
|
||||
className?: string;
|
||||
signing?: boolean;
|
||||
customModal?: typeof ConfirmationModal;
|
||||
}> = ({ signing, customModal, className }) => (
|
||||
<React.Fragment>
|
||||
<SendScheduleTransactionButtonFactory
|
||||
signing={signing}
|
||||
Modal={customModal ? customModal : ConfirmationModal}
|
||||
withProps={({ disabled, openModal, signTx }) => (
|
||||
<React.Fragment>
|
||||
<button
|
||||
disabled={disabled}
|
||||
className={`SendButton btn btn-primary btn-block ${className}`}
|
||||
onClick={() => {
|
||||
!!signing ? (signTx(), openModal()) : openModal();
|
||||
}}
|
||||
>
|
||||
{translate('SCHEDULE_schedule')}
|
||||
</button>
|
||||
</React.Fragment>
|
||||
)}
|
||||
/>
|
||||
<SigningStatus />
|
||||
</React.Fragment>
|
||||
);
|
|
@ -0,0 +1,29 @@
|
|||
import { getWalletType } from 'selectors/wallet';
|
||||
import { connect } from 'react-redux';
|
||||
import { AppState } from 'reducers';
|
||||
import {
|
||||
getSerializedTransaction,
|
||||
isNetworkRequestPending,
|
||||
isValidGasPrice,
|
||||
isValidGasLimit,
|
||||
getSignedTx,
|
||||
getWeb3Tx,
|
||||
getSchedulingTransaction
|
||||
} from 'selectors/transaction';
|
||||
import { SendButtonFactoryClass } from 'components/SendButtonFactory';
|
||||
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
walletType: getWalletType(state),
|
||||
serializedTransaction: getSerializedTransaction(state),
|
||||
...getSchedulingTransaction(state),
|
||||
networkRequestPending: isNetworkRequestPending(state),
|
||||
validGasPrice: isValidGasPrice(state),
|
||||
validGasLimit: isValidGasLimit(state),
|
||||
signedTx: !!getSignedTx(state) || !!getWeb3Tx(state)
|
||||
};
|
||||
};
|
||||
|
||||
export const SendScheduleTransactionButtonFactory = connect(mapStateToProps)(
|
||||
SendButtonFactoryClass
|
||||
);
|
|
@ -7,8 +7,8 @@ import { getWalletInst } from 'selectors/wallet';
|
|||
import { AppState } from 'reducers';
|
||||
import { RouteComponentProps, Redirect } from 'react-router';
|
||||
import { UnavailableWallets, SchedulingFields } from 'containers/Tabs/SendTransaction/components';
|
||||
import { isNetworkUnit } from 'selectors/config/wallet';
|
||||
import { SideBar } from '../SendTransaction/components/SideBar';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
|
||||
const ScheduleMain = () => (
|
||||
<React.Fragment>
|
||||
|
@ -18,16 +18,19 @@ const ScheduleMain = () => (
|
|||
);
|
||||
|
||||
interface StateProps {
|
||||
schedulingDisabled: boolean;
|
||||
wallet: AppState['wallet']['inst'];
|
||||
requestDisabled: boolean;
|
||||
}
|
||||
|
||||
type Props = StateProps & RouteComponentProps<{}>;
|
||||
|
||||
class Schedule extends React.Component<Props> {
|
||||
public render() {
|
||||
const { wallet, match } = this.props;
|
||||
const currentPath = match.url;
|
||||
const { schedulingDisabled, wallet } = this.props;
|
||||
|
||||
if (schedulingDisabled && wallet) {
|
||||
return <Redirect to="account/info" />;
|
||||
}
|
||||
|
||||
return (
|
||||
<TabSection>
|
||||
|
@ -36,7 +39,7 @@ class Schedule extends React.Component<Props> {
|
|||
{wallet && (
|
||||
<div className="SubTabs row">
|
||||
<div className="col-sm-8">
|
||||
{wallet.isReadOnly ? <Redirect to={`${currentPath}/info`} /> : <ScheduleMain />};
|
||||
{wallet.isReadOnly ? <Redirect to="schedule/info" /> : <ScheduleMain />};
|
||||
</div>
|
||||
<SideBar />
|
||||
</div>
|
||||
|
@ -49,5 +52,5 @@ class Schedule extends React.Component<Props> {
|
|||
|
||||
export default connect((state: AppState) => ({
|
||||
wallet: getWalletInst(state),
|
||||
requestDisabled: !isNetworkUnit(state, 'ETH')
|
||||
schedulingDisabled: getNetworkConfig(state).name !== 'Kovan'
|
||||
}))(Schedule);
|
|
@ -8,16 +8,23 @@ import {
|
|||
CurrentCustomMessage,
|
||||
GenerateTransaction,
|
||||
SendButton,
|
||||
SigningStatus,
|
||||
WindowStartField
|
||||
WindowStartField,
|
||||
ScheduleTimestampField,
|
||||
ScheduleTimezoneDropDown,
|
||||
TimeBountyField,
|
||||
ScheduleType,
|
||||
WindowSizeField,
|
||||
ScheduleGasPriceField
|
||||
} from 'components';
|
||||
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
|
||||
import translate from 'translations';
|
||||
|
||||
import { AppState } from 'reducers';
|
||||
import { NonStandardTransaction } from './components';
|
||||
import { getCurrentWindowStart, ICurrentWindowStart } from 'selectors/transaction';
|
||||
import { getNetworkConfig } from 'selectors/config';
|
||||
import { getOffline } from 'selectors/config';
|
||||
import { SendScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton';
|
||||
import { GenerateScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/GenerateScheduleTransactionButton';
|
||||
import { getCurrentScheduleType, ICurrentScheduleType } from 'selectors/transaction';
|
||||
|
||||
const QueryWarning: React.SFC<{}> = () => (
|
||||
<WhenQueryExists
|
||||
|
@ -30,56 +37,15 @@ const QueryWarning: React.SFC<{}> = () => (
|
|||
);
|
||||
|
||||
interface StateProps {
|
||||
schedulingDisabled: boolean;
|
||||
scheduling: boolean;
|
||||
shouldDisplay: boolean;
|
||||
offline: boolean;
|
||||
windowStart: ICurrentWindowStart;
|
||||
schedulingType: ICurrentScheduleType;
|
||||
}
|
||||
|
||||
class FieldsClass extends Component<StateProps> {
|
||||
public render() {
|
||||
const { schedulingDisabled, shouldDisplay, windowStart } = this.props;
|
||||
|
||||
const scheduling = Boolean(windowStart.value);
|
||||
|
||||
const content = (
|
||||
<div className="Tab-content-pane">
|
||||
<AddressField />
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<AmountField hasUnitDropdown={true} />
|
||||
<SendEverything />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!schedulingDisabled && (
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<WindowStartField />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<TXMetaDataPanel scheduling={scheduling} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CurrentCustomMessage />
|
||||
<NonStandardTransaction />
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12 clearfix">
|
||||
<GenerateTransaction scheduling={scheduling} />
|
||||
</div>
|
||||
</div>
|
||||
<SigningStatus />
|
||||
<div className="row form-group">
|
||||
<SendButton />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const { shouldDisplay, scheduling, schedulingType } = this.props;
|
||||
|
||||
return (
|
||||
<OnlyUnlocked
|
||||
|
@ -95,16 +61,61 @@ class FieldsClass extends Component<StateProps> {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{scheduling && (
|
||||
<div className="scheduled-tx-settings">
|
||||
<h6>Scheduled Transaction Settings</h6>
|
||||
<br />
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-3">
|
||||
<ScheduleType />
|
||||
</div>
|
||||
|
||||
{schedulingType.value === 'time' && (
|
||||
<div>
|
||||
<div className="col-xs-12 col-md-3">
|
||||
<ScheduleTimestampField />
|
||||
</div>
|
||||
<div className="col-xs-12 col-md-3">
|
||||
<ScheduleTimezoneDropDown />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{schedulingType.value === 'block' && (
|
||||
<div>
|
||||
<div className="col-xs-12 col-md-6">
|
||||
<WindowStartField />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="col-xs-12 col-md-3">
|
||||
<WindowSizeField />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-6">
|
||||
<ScheduleGasPriceField />
|
||||
</div>
|
||||
<div className="col-xs-6">
|
||||
<TimeBountyField />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<TXMetaDataPanel />
|
||||
<TXMetaDataPanel scheduling={scheduling} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CurrentCustomMessage />
|
||||
<NonStandardTransaction />
|
||||
|
||||
{offline ? <GenerateTransaction /> : <SendButton signing={true} />}
|
||||
{this.getTxButton()}
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
|
@ -112,11 +123,29 @@ class FieldsClass extends Component<StateProps> {
|
|||
/>
|
||||
);
|
||||
}
|
||||
|
||||
private getTxButton() {
|
||||
const { offline, scheduling } = this.props;
|
||||
|
||||
if (scheduling) {
|
||||
if (offline) {
|
||||
return <GenerateScheduleTransactionButton />;
|
||||
}
|
||||
|
||||
return <SendScheduleTransactionButton signing={true} />;
|
||||
}
|
||||
|
||||
if (offline) {
|
||||
return <GenerateTransaction />;
|
||||
}
|
||||
|
||||
return <SendButton signing={true} />;
|
||||
}
|
||||
}
|
||||
|
||||
export const Fields = connect((state: AppState) => ({
|
||||
scheduling: true,
|
||||
shouldDisplay: !isAnyOfflineWithWeb3(state),
|
||||
offline: getOffline(state),
|
||||
windowStart: getCurrentWindowStart(state),
|
||||
schedulingDisabled: getNetworkConfig(state).name !== 'Kovan'
|
||||
schedulingType: getCurrentScheduleType(state)
|
||||
}))(FieldsClass);
|
||||
|
|
|
@ -5,11 +5,7 @@ import {
|
|||
AddressField,
|
||||
AmountField,
|
||||
TXMetaDataPanel,
|
||||
SendEverything,
|
||||
CurrentCustomMessage,
|
||||
GenerateTransaction,
|
||||
SendButton,
|
||||
SigningStatus,
|
||||
WindowStartField
|
||||
} from 'components';
|
||||
import { OnlyUnlocked, WhenQueryExists } from 'components/renderCbs';
|
||||
|
@ -18,6 +14,9 @@ import translate from 'translations';
|
|||
import { AppState } from 'reducers';
|
||||
import { NonStandardTransaction } from './components';
|
||||
import { NewTabLink } from 'components/ui';
|
||||
import { getOffline } from 'selectors/config';
|
||||
import { SendScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/SendScheduleTransactionButton';
|
||||
import { GenerateScheduleTransactionButton } from 'containers/Tabs/ScheduleTransaction/components/GenerateScheduleTransactionButton';
|
||||
|
||||
const EACLink = () => (
|
||||
<NewTabLink href="https://chronologic.network" content="Ethereum Alarm Clock" />
|
||||
|
@ -35,64 +34,62 @@ const QueryWarning: React.SFC<{}> = () => (
|
|||
|
||||
interface StateProps {
|
||||
shouldDisplay: boolean;
|
||||
offline: boolean;
|
||||
}
|
||||
|
||||
class SchedulingFieldsClass extends Component<StateProps> {
|
||||
public render() {
|
||||
const { shouldDisplay } = this.props;
|
||||
|
||||
const content = (
|
||||
<div className="Tab-content-pane">
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<h3>ChronoLogic Scheduler</h3>
|
||||
Powered by the <EACLink />, ChronoLogic Scheduler is a decentralized scheduling protocol
|
||||
based on the Ethereum blockchain.
|
||||
</div>
|
||||
</div>
|
||||
<div className="row form-group" />
|
||||
|
||||
<AddressField />
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<AmountField hasUnitDropdown={true} />
|
||||
<SendEverything />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<WindowStartField />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<TXMetaDataPanel scheduling={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CurrentCustomMessage />
|
||||
<NonStandardTransaction />
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12 clearfix">
|
||||
<GenerateTransaction scheduling={true} />
|
||||
</div>
|
||||
</div>
|
||||
<SigningStatus />
|
||||
<div className="row form-group">
|
||||
<SendButton />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const { shouldDisplay, offline } = this.props;
|
||||
|
||||
return (
|
||||
<OnlyUnlocked
|
||||
whenUnlocked={
|
||||
<React.Fragment>
|
||||
<QueryWarning />
|
||||
{shouldDisplay ? content : null}
|
||||
{shouldDisplay && (
|
||||
<div className="Tab-content-pane">
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<h3>ChronoLogic Scheduler</h3>
|
||||
Powered by the <EACLink />, ChronoLogic Scheduler is a decentralized scheduling
|
||||
protocol based on the Ethereum blockchain.
|
||||
</div>
|
||||
</div>
|
||||
<div className="row form-group" />
|
||||
|
||||
<AddressField />
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<AmountField hasUnitDropdown={true} hasSendEverything={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<WindowStartField />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12">
|
||||
<TXMetaDataPanel scheduling={true} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CurrentCustomMessage />
|
||||
<NonStandardTransaction />
|
||||
|
||||
<div className="row form-group">
|
||||
<div className="col-xs-12 clearfix">
|
||||
{offline ? (
|
||||
<GenerateScheduleTransactionButton />
|
||||
) : (
|
||||
<SendScheduleTransactionButton signing={true} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
|
@ -101,5 +98,6 @@ class SchedulingFieldsClass extends Component<StateProps> {
|
|||
}
|
||||
|
||||
export const SchedulingFields = connect((state: AppState) => ({
|
||||
shouldDisplay: !isAnyOfflineWithWeb3(state)
|
||||
shouldDisplay: !isAnyOfflineWithWeb3(state),
|
||||
offline: getOffline(state)
|
||||
}))(SchedulingFieldsClass);
|
||||
|
|
|
@ -2,6 +2,7 @@ import BN from 'bn.js';
|
|||
import abi from 'ethereumjs-abi';
|
||||
|
||||
export const EAC_SCHEDULING_CONFIG = {
|
||||
DAPP_ADDRESS: 'https://app.chronologic.network',
|
||||
FEE: new BN('2242000000000000'), // $2
|
||||
FEE_MULTIPLIER: new BN('2'),
|
||||
FUTURE_EXECUTION_COST: new BN('180000'),
|
||||
|
@ -65,3 +66,7 @@ export const getScheduleData = (
|
|||
requiredDeposit
|
||||
]);
|
||||
};
|
||||
|
||||
export const getTXDetailsCheckURL = (txHash: string) => {
|
||||
return `${EAC_SCHEDULING_CONFIG.DAPP_ADDRESS}/awaiting/scheduler/${txHash}`;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
import { SagaIterator } from 'redux-saga';
|
||||
import { getWeb3Tx, getSignedTx, getTransactionStatus } from 'selectors/transaction';
|
||||
import {
|
||||
getWeb3Tx,
|
||||
getSignedTx,
|
||||
getTransactionStatus,
|
||||
getWindowStart,
|
||||
ICurrentWindowStart
|
||||
} from 'selectors/transaction';
|
||||
import { select, call, put } from 'redux-saga/effects';
|
||||
import {
|
||||
broadcastTransactionFailed,
|
||||
|
@ -50,14 +56,18 @@ export const broadcastTransactionWrapper = (func: (serializedTx: string) => Saga
|
|||
const broadcastedHash: string = yield call(func, stringTx); // convert to string because node / web3 doesnt support buffers
|
||||
yield put(broadcastTransactionSucceeded({ indexingHash, broadcastedHash }));
|
||||
|
||||
const windowStart: ICurrentWindowStart = yield select(getWindowStart);
|
||||
const network: NetworkConfig = yield select(getNetworkConfig);
|
||||
|
||||
const scheduling = Boolean(windowStart && windowStart.value);
|
||||
|
||||
yield put(
|
||||
showNotification(
|
||||
'success',
|
||||
<TransactionSucceeded
|
||||
txHash={broadcastedHash}
|
||||
blockExplorer={network.isCustom ? undefined : network.blockExplorer}
|
||||
scheduling={scheduling}
|
||||
/>,
|
||||
Infinity
|
||||
)
|
||||
|
|
|
@ -31,12 +31,6 @@ export interface IGetTransaction {
|
|||
isFullTransaction: boolean; //if the user has filled all the fields
|
||||
}
|
||||
|
||||
export interface IGetSchedulingTransaction {
|
||||
transaction: EthTx;
|
||||
isFullTransaction: boolean;
|
||||
isWindowStartValid: boolean;
|
||||
}
|
||||
|
||||
const getTransaction = (state: AppState): IGetTransaction => {
|
||||
const currentTo = getCurrentTo(state);
|
||||
const currentValue = getCurrentValue(state);
|
||||
|
@ -59,7 +53,7 @@ const getTransaction = (state: AppState): IGetTransaction => {
|
|||
return { transaction, isFullTransaction };
|
||||
};
|
||||
|
||||
const getSchedulingTransaction = (state: AppState): IGetSchedulingTransaction => {
|
||||
const getSchedulingTransaction = (state: AppState): IGetTransaction => {
|
||||
const currentTo = getCurrentTo(state);
|
||||
const currentValue = getCurrentValue(state);
|
||||
const transactionFields = getFields(state);
|
||||
|
@ -72,16 +66,11 @@ const getSchedulingTransaction = (state: AppState): IGetSchedulingTransaction =>
|
|||
const nonce = getNonce(state);
|
||||
const gasPrice = getGasPrice(state);
|
||||
const timeBounty = getTimeBounty(state);
|
||||
const windowStartValid = isWindowStartValid(transactionFields, getLatestBlock(state));
|
||||
|
||||
const isFullTransaction = isFullTx(
|
||||
state,
|
||||
transactionFields,
|
||||
currentTo,
|
||||
currentValue,
|
||||
dataExists,
|
||||
validGasCost,
|
||||
unit
|
||||
);
|
||||
const isFullTransaction =
|
||||
isFullTx(state, transactionFields, currentTo, currentValue, dataExists, validGasCost, unit) &&
|
||||
windowStartValid;
|
||||
|
||||
const transactionData = getScheduleData(
|
||||
currentTo.raw,
|
||||
|
@ -119,8 +108,7 @@ const getSchedulingTransaction = (state: AppState): IGetSchedulingTransaction =>
|
|||
|
||||
return {
|
||||
transaction,
|
||||
isFullTransaction,
|
||||
isWindowStartValid: isWindowStartValid(transactionFields, getLatestBlock(state))
|
||||
isFullTransaction
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
"ledgerco": "1.2.1",
|
||||
"lodash": "4.17.5",
|
||||
"moment": "2.22.0",
|
||||
"moment-timezone": "0.5.14",
|
||||
"normalizr": "3.2.4",
|
||||
"pikaday-time": "1.6.1",
|
||||
"qrcode": "1.2.0",
|
||||
"qrcode.react": "0.8.0",
|
||||
"query-string": "6.0.0",
|
||||
|
@ -60,6 +62,7 @@
|
|||
"@types/history": "4.6.2",
|
||||
"@types/jest": "22.2.2",
|
||||
"@types/lodash": "4.14.106",
|
||||
"@types/moment-timezone": "0.5.4",
|
||||
"@types/qrcode": "0.8.0",
|
||||
"@types/qrcode.react": "0.6.3",
|
||||
"@types/query-string": "5.1.0",
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import { getWeb3Tx, getSignedTx, getTransactionStatus } from 'selectors/transaction';
|
||||
import {
|
||||
getWeb3Tx,
|
||||
getSignedTx,
|
||||
getTransactionStatus,
|
||||
getWindowStart
|
||||
} from 'selectors/transaction';
|
||||
import { select, call, put } from 'redux-saga/effects';
|
||||
import {
|
||||
broadcastTransactionFailed,
|
||||
|
@ -118,6 +123,10 @@ describe('broadcastTransactionWrapper*', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('select getWindowStart', () => {
|
||||
expect(gens.gen.next().value).toEqual(select(getWindowStart));
|
||||
});
|
||||
|
||||
it('select getNetworkConfig', () => {
|
||||
expect(gens.gen.next().value).toEqual(select(getNetworkConfig));
|
||||
});
|
||||
|
@ -127,7 +136,11 @@ describe('broadcastTransactionWrapper*', () => {
|
|||
put(
|
||||
showNotification(
|
||||
'success',
|
||||
<TransactionSucceeded txHash={broadcastedHash} blockExplorer={network.blockExplorer} />,
|
||||
<TransactionSucceeded
|
||||
txHash={broadcastedHash}
|
||||
blockExplorer={network.blockExplorer}
|
||||
scheduling={false}
|
||||
/>,
|
||||
Infinity
|
||||
)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue