Advanced Options refactor (#2029)

* useEstimateTxGas: set the correct value of isOffChainSignature if gas estimation fails
This commit is contained in:
nicolas 2021-03-23 05:01:49 -03:00 committed by GitHub
parent 253137d2ba
commit da9031568f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 153 additions and 121 deletions

View File

@ -218,10 +218,9 @@ export const useEstimateTransactionGas = ({
) )
const fixedGasCosts = getFixedGasCosts(Number(threshold)) const fixedGasCosts = getFixedGasCosts(Number(threshold))
const isOffChainSignature = checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)
try { try {
const isOffChainSignature = checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)
const gasEstimation = await estimateTransactionGas({ const gasEstimation = await estimateTransactionGas({
safeAddress, safeAddress,
txRecipient, txRecipient,
@ -279,7 +278,7 @@ export const useEstimateTransactionGas = ({
gasLimit: '0', gasLimit: '0',
isExecution, isExecution,
isCreation, isCreation,
isOffChainSignature: false, isOffChainSignature,
}) })
} }
} }

View File

@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react'
import { Icon, ModalFooterConfirmation, Text, Title } from '@gnosis.pm/safe-react-components' import { Icon, ModalFooterConfirmation, Text, Title } from '@gnosis.pm/safe-react-components'
import { Transaction } from '@gnosis.pm/safe-apps-sdk-v1' import { Transaction } from '@gnosis.pm/safe-apps-sdk-v1'
import styled from 'styled-components' import styled from 'styled-components'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch } from 'react-redux'
import AddressInfo from 'src/components/AddressInfo' import AddressInfo from 'src/components/AddressInfo'
import DividerLine from 'src/components/DividerLine' import DividerLine from 'src/components/DividerLine'
@ -26,7 +26,6 @@ import GasEstimationInfo from './GasEstimationInfo'
import { getNetworkInfo } from 'src/config' import { getNetworkInfo } from 'src/config'
import { TransactionParams } from './AppFrame' import { TransactionParams } from './AppFrame'
import { EstimationStatus, useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' import { EstimationStatus, useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas'
import { safeThresholdSelector } from 'src/logic/safe/store/selectors'
import Modal from 'src/components/Modal' import Modal from 'src/components/Modal'
import Row from 'src/components/layout/Row' import Row from 'src/components/layout/Row'
import Hairline from 'src/components/layout/Hairline' import Hairline from 'src/components/layout/Hairline'
@ -123,7 +122,6 @@ export const ConfirmTransactionModal = ({
onTxReject, onTxReject,
}: OwnProps): React.ReactElement | null => { }: OwnProps): React.ReactElement | null => {
const [estimatedSafeTxGas, setEstimatedSafeTxGas] = useState(0) const [estimatedSafeTxGas, setEstimatedSafeTxGas] = useState(0)
const threshold = useSelector(safeThresholdSelector) || 1
const txRecipient: string | undefined = useMemo(() => (txs.length > 1 ? MULTI_SEND_ADDRESS : txs[0]?.to), [txs]) const txRecipient: string | undefined = useMemo(() => (txs.length > 1 ? MULTI_SEND_ADDRESS : txs[0]?.to), [txs])
const txData: string | undefined = useMemo(() => (txs.length > 1 ? encodeMultiSendCall(txs) : txs[0]?.data), [txs]) const txData: string | undefined = useMemo(() => (txs.length > 1 ? encodeMultiSendCall(txs) : txs[0]?.data), [txs])
@ -174,8 +172,6 @@ export const ConfirmTransactionModal = ({
onClose() onClose()
} }
const getParametersStatus = () => (threshold > 1 ? 'ETH_DISABLED' : 'ENABLED')
const confirmTransactions = async (txParameters: TxParameters) => { const confirmTransactions = async (txParameters: TxParameters) => {
await dispatch( await dispatch(
createTransaction( createTransaction(
@ -274,9 +270,9 @@ export const ConfirmTransactionModal = ({
<TxParametersDetail <TxParametersDetail
txParameters={txParameters} txParameters={txParameters}
onEdit={toggleEditMode} onEdit={toggleEditMode}
parametersStatus={getParametersStatus()}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Container> </Container>
{txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : (
@ -297,16 +293,16 @@ export const ConfirmTransactionModal = ({
return ( return (
<Modal description="Safe App transaction" title="Safe App transaction" open> <Modal description="Safe App transaction" title="Safe App transaction" open>
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
parametersStatus={getParametersStatus()}
closeEditModalCallback={closeEditModalCallback} closeEditModalCallback={closeEditModalCallback}
> >
{(txParameters, toggleEditMode) => ( {(txParameters, toggleEditMode) => (
<> <>
<ModalTitle title={app.name} iconUrl={app.iconUrl} onClose={handleTxRejection} /> <ModalTitle title={app.name} iconUrl={app.iconUrl} onClose={handleTxRejection} />
<Hairline /> <Hairline />
{body(txParameters, toggleEditMode)} {body(txParameters, toggleEditMode)}

View File

@ -126,6 +126,8 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -210,6 +212,7 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
<div className={classes.gasCostsContainer}> <div className={classes.gasCostsContainer}>

View File

@ -94,7 +94,13 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => {
} }
return ( return (
<EditableTxParameters ethGasLimit={gasLimit} ethGasPrice={gasPriceFormatted} safeTxGas={gasEstimation.toString()}> <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()}
>
{(txParameters, toggleEditMode) => ( {(txParameters, toggleEditMode) => (
<> <>
<Row align="center" className={classes.heading} grow> <Row align="center" className={classes.heading} grow>
@ -168,6 +174,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => {
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
{txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : (

View File

@ -140,6 +140,8 @@ const ReviewCollectible = ({ onClose, onPrev, tx }: Props): React.ReactElement =
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -206,6 +208,7 @@ const ReviewCollectible = ({ onClose, onPrev, tx }: Props): React.ReactElement =
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
<div className={classes.gasCostsContainer}> <div className={classes.gasCostsContainer}>

View File

@ -178,6 +178,8 @@ const ReviewSendFundsTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactE
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -260,10 +262,11 @@ const ReviewSendFundsTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactE
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
{/* Disclaimer */}
</Block> </Block>
{/* Disclaimer */}
{txEstimationExecutionStatus !== EstimationStatus.LOADING && ( {txEstimationExecutionStatus !== EstimationStatus.LOADING && (
<div className={classes.gasCostsContainer}> <div className={classes.gasCostsContainer}>
<TransactionFees <TransactionFees

View File

@ -127,6 +127,8 @@ export const RemoveModuleModal = ({ onClose, selectedModulePair }: RemoveModuleM
open open
> >
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -181,6 +183,7 @@ export const RemoveModuleModal = ({ onClose, selectedModulePair }: RemoveModuleM
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
<Row className={cn(classes.modalDescription, classes.gasCostsContainer)}> <Row className={cn(classes.modalDescription, classes.gasCostsContainer)}>

View File

@ -101,6 +101,8 @@ export const ReviewAddOwner = ({ onClickBack, onClose, onSubmit, values }: Revie
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -214,6 +216,7 @@ export const ReviewAddOwner = ({ onClickBack, onClose, onSubmit, values }: Revie
compact={false} compact={false}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
<Block className={classes.gasCostsContainer}> <Block className={classes.gasCostsContainer}>

View File

@ -123,6 +123,8 @@ export const ReviewRemoveOwnerModal = ({
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -241,6 +243,7 @@ export const ReviewRemoveOwnerModal = ({
compact={false} compact={false}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
{txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : (

View File

@ -120,6 +120,8 @@ export const ReviewReplaceOwnerModal = ({
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -261,6 +263,7 @@ export const ReviewReplaceOwnerModal = ({
compact={false} compact={false}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
<Block className={classes.gasCostsContainer}> <Block className={classes.gasCostsContainer}>

View File

@ -233,6 +233,8 @@ export const ReviewSpendingLimits = ({ onBack, onClose, txToken, values }: Revie
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -282,6 +284,7 @@ export const ReviewSpendingLimits = ({ onBack, onClose, txToken, values }: Revie
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
<div className={classes.gasCostsContainer}> <div className={classes.gasCostsContainer}>

View File

@ -116,6 +116,8 @@ export const RemoveLimitModal = ({ onClose, spendingLimit, open }: RemoveSpendin
description="Remove the selected Spending Limit" description="Remove the selected Spending Limit"
> >
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -148,6 +150,7 @@ export const RemoveLimitModal = ({ onClose, spendingLimit, open }: RemoveSpendin
onEdit={toggleEditMode} onEdit={toggleEditMode}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>

View File

@ -84,8 +84,6 @@ export const ChangeThresholdModal = ({
} }
}, [safeAddress, editedThreshold]) }, [safeAddress, editedThreshold])
const getParametersStatus = () => (threshold > 1 ? 'ETH_DISABLED' : 'ENABLED')
const handleSubmit = async ({ txParameters }) => { const handleSubmit = async ({ txParameters }) => {
await dispatch( await dispatch(
createTransaction({ createTransaction({
@ -120,6 +118,8 @@ export const ChangeThresholdModal = ({
return ( return (
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()} safeTxGas={gasEstimation.toString()}
@ -181,9 +181,9 @@ export const ChangeThresholdModal = ({
<TxParametersDetail <TxParametersDetail
txParameters={txParameters} txParameters={txParameters}
onEdit={toggleEditMode} onEdit={toggleEditMode}
parametersStatus={getParametersStatus()}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
{txEstimationExecutionStatus !== EstimationStatus.LOADING && ( {txEstimationExecutionStatus !== EstimationStatus.LOADING && (

View File

@ -76,7 +76,13 @@ export const UpdateSafeModal = ({ onClose, safeAddress }: Props): React.ReactEle
}) })
return ( return (
<EditableTxParameters ethGasLimit={gasLimit} ethGasPrice={gasPriceFormatted} safeTxGas={gasEstimation.toString()}> <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted}
safeTxGas={gasEstimation.toString()}
>
{(txParameters, toggleEditMode) => ( {(txParameters, toggleEditMode) => (
<> <>
<Row align="center" className={classes.heading} grow> <Row align="center" className={classes.heading} grow>
@ -116,6 +122,7 @@ export const UpdateSafeModal = ({ onClose, safeAddress }: Props): React.ReactEle
compact={false} compact={false}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>
{txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : (

View File

@ -317,6 +317,8 @@ export const ApproveTxModal = ({
return ( return (
<Modal description={description} handleClose={onClose} open={isOpen} title={title}> <Modal description={description} handleClose={onClose} open={isOpen} title={title}>
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
parametersStatus={getParametersStatus()} parametersStatus={getParametersStatus()}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
@ -370,13 +372,14 @@ export const ApproveTxModal = ({
)} )}
{/* Tx Parameters */} {/* Tx Parameters */}
{approveAndExecute && ( {(approveAndExecute || !isOffChainSignature) && (
<TxParametersDetail <TxParametersDetail
txParameters={txParameters} txParameters={txParameters}
onEdit={toggleEditMode} onEdit={toggleEditMode}
parametersStatus={getParametersStatus()} parametersStatus={getParametersStatus()}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
)} )}
</Row> </Row>

View File

@ -82,6 +82,8 @@ export const RejectTxModal = ({ isOpen, onClose, gwTransaction }: Props): React.
return ( return (
<Modal description="Reject Transaction" handleClose={onClose} open={isOpen} title="Reject Transaction"> <Modal description="Reject Transaction" handleClose={onClose} open={isOpen} title="Reject Transaction">
<EditableTxParameters <EditableTxParameters
isOffChainSignature={isOffChainSignature}
isExecution={isExecution}
ethGasLimit={gasLimit} ethGasLimit={gasLimit}
ethGasPrice={gasPriceFormatted} ethGasPrice={gasPriceFormatted}
safeTxGas={'0'} safeTxGas={'0'}
@ -119,6 +121,7 @@ export const RejectTxModal = ({ isOpen, onClose, gwTransaction }: Props): React.
parametersStatus={getParametersStatus()} parametersStatus={getParametersStatus()}
isTransactionCreation={isCreation} isTransactionCreation={isCreation}
isTransactionExecution={isExecution} isTransactionExecution={isExecution}
isOffChainSignature={isOffChainSignature}
/> />
</Block> </Block>

View File

@ -15,11 +15,11 @@ import GnoForm from 'src/components/forms/GnoForm'
import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters'
import { composeValidators, minValue } from 'src/components/forms/validator' import { composeValidators, minValue } from 'src/components/forms/validator'
import { ParametersStatus, areSafeParamsEnabled, areEthereumParamsEnabled } from '../utils' import { ParametersStatus, areSafeParamsEnabled, areEthereumParamsVisible, ethereumTxParametersTitle } from '../utils'
import { getNetworkInfo } from 'src/config' import { getNetworkInfo } from 'src/config'
const StyledDivider = styled(Divider)` const StyledDivider = styled(Divider)`
margin: 0px; margin: 16px 0;
` `
const SafeOptions = styled.div` const SafeOptions = styled.div`
@ -39,7 +39,7 @@ const EthereumOptions = styled.div`
} }
` `
const StyledLink = styled(Link)` const StyledLink = styled(Link)`
margin: 16px 0; margin: 16px 0 0 0;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@ -65,6 +65,7 @@ interface Props {
txParameters: TxParameters txParameters: TxParameters
onClose: (txParameters?: TxParameters) => void onClose: (txParameters?: TxParameters) => void
parametersStatus: ParametersStatus parametersStatus: ParametersStatus
isExecution: boolean
} }
const formValidation = (values) => { const formValidation = (values) => {
@ -101,6 +102,7 @@ export const EditTxParametersForm = ({
onClose, onClose,
txParameters, txParameters,
parametersStatus = 'ENABLED', parametersStatus = 'ENABLED',
isExecution,
}: Props): React.ReactElement => { }: Props): React.ReactElement => {
const classes = useStyles() const classes = useStyles()
const { safeNonce, safeTxGas, ethNonce, ethGasLimit, ethGasPrice } = txParameters const { safeNonce, safeTxGas, ethNonce, ethGasLimit, ethGasPrice } = txParameters
@ -142,7 +144,7 @@ export const EditTxParametersForm = ({
{() => ( {() => (
<> <>
<StyledText size="xl" strong> <StyledText size="xl" strong>
Safe transactions parameters Safe transaction
</StyledText> </StyledText>
<SafeOptions> <SafeOptions>
@ -168,49 +170,53 @@ export const EditTxParametersForm = ({
/> />
</SafeOptions> </SafeOptions>
<StyledTextMt size="xl" strong> {areEthereumParamsVisible(parametersStatus) && (
Ethereum transactions parameters <>
</StyledTextMt> <StyledTextMt size="xl" strong>
{ethereumTxParametersTitle(isExecution)}
</StyledTextMt>
<EthereumOptions> <EthereumOptions>
<Field <Field
name="ethNonce" name="ethNonce"
defaultValue={ethNonce} defaultValue={ethNonce}
placeholder="Ethereum nonce" placeholder="Nonce"
text="Ethereum nonce" text="Nonce"
type="number" type="number"
component={TextField} component={TextField}
disabled={!areEthereumParamsEnabled(parametersStatus)} disabled={!areEthereumParamsVisible(parametersStatus)}
/> />
<Field <Field
name="ethGasLimit" name="ethGasLimit"
defaultValue={ethGasLimit} defaultValue={ethGasLimit}
placeholder="Ethereum gas limit" placeholder="Gas limit"
text="Ethereum gas limit" text="Gas limit"
type="number" type="number"
component={TextField} component={TextField}
disabled={parametersStatus === 'CANCEL_TRANSACTION'} disabled={parametersStatus === 'CANCEL_TRANSACTION'}
/> />
<Field <Field
name="ethGasPrice" name="ethGasPrice"
defaultValue={ethGasPrice} defaultValue={ethGasPrice}
type="number" type="number"
placeholder="Ethereum gas price (GWEI)" placeholder="Gas price (GWEI)"
text="Ethereum gas price (GWEI)" text="Gas price (GWEI)"
component={TextField} component={TextField}
disabled={!areEthereumParamsEnabled(parametersStatus)} disabled={!areEthereumParamsVisible(parametersStatus)}
/> />
</EthereumOptions> </EthereumOptions>
<StyledLink <StyledLink
href="https://help.gnosis-safe.io/en/articles/4738445-configure-advanced-transaction-parameters-manually" href="https://help.gnosis-safe.io/en/articles/4738445-configure-advanced-transaction-parameters-manually"
target="_blank" target="_blank"
> >
<Text size="xl" color="primary"> <Text size="xl" color="primary">
How can I configure the gas price manually? How can I configure these parameters manually?
</Text> </Text>
<Icon size="sm" type="externalLink" color="primary" /> <Icon size="sm" type="externalLink" color="primary" />
</StyledLink> </StyledLink>
</>
)}
<StyledDivider /> <StyledDivider />

View File

@ -7,6 +7,8 @@ import { safeThresholdSelector } from 'src/logic/safe/store/selectors'
type Props = { type Props = {
children: (txParameters: TxParameters, toggleStatus: (txParameters?: TxParameters) => void) => any children: (txParameters: TxParameters, toggleStatus: (txParameters?: TxParameters) => void) => any
isOffChainSignature: boolean
isExecution: boolean
parametersStatus?: ParametersStatus parametersStatus?: ParametersStatus
ethGasLimit?: TxParameters['ethGasLimit'] ethGasLimit?: TxParameters['ethGasLimit']
ethGasPrice?: TxParameters['ethGasPrice'] ethGasPrice?: TxParameters['ethGasPrice']
@ -17,6 +19,8 @@ type Props = {
export const EditableTxParameters = ({ export const EditableTxParameters = ({
children, children,
isOffChainSignature,
isExecution,
parametersStatus, parametersStatus,
ethGasLimit, ethGasLimit,
ethGasPrice, ethGasPrice,
@ -27,7 +31,7 @@ export const EditableTxParameters = ({
const [isEditMode, toggleEditMode] = useState(false) const [isEditMode, toggleEditMode] = useState(false)
const [useManualValues, setUseManualValues] = useState(false) const [useManualValues, setUseManualValues] = useState(false)
const threshold = useSelector(safeThresholdSelector) || 1 const threshold = useSelector(safeThresholdSelector) || 1
const defaultParameterStatus = threshold > 1 ? 'ETH_DISABLED' : 'ENABLED' const defaultParameterStatus = isOffChainSignature && threshold > 1 ? 'ETH_HIDDEN' : 'ENABLED'
const txParameters = useTransactionParameters({ const txParameters = useTransactionParameters({
parameterStatus: parametersStatus || defaultParameterStatus, parameterStatus: parametersStatus || defaultParameterStatus,
initialEthGasLimit: ethGasLimit, initialEthGasLimit: ethGasLimit,
@ -65,6 +69,7 @@ export const EditableTxParameters = ({
return isEditMode ? ( return isEditMode ? (
<EditTxParametersForm <EditTxParametersForm
isExecution={isExecution}
txParameters={txParameters} txParameters={txParameters}
onClose={closeEditFormHandler} onClose={closeEditFormHandler}
parametersStatus={parametersStatus ? parametersStatus : defaultParameterStatus} parametersStatus={parametersStatus ? parametersStatus : defaultParameterStatus}

View File

@ -3,7 +3,7 @@ import styled from 'styled-components'
import { Text, ButtonLink, Accordion, AccordionSummary, AccordionDetails } from '@gnosis.pm/safe-react-components' import { Text, ButtonLink, Accordion, AccordionSummary, AccordionDetails } from '@gnosis.pm/safe-react-components'
import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters'
import { ParametersStatus, areEthereumParamsEnabled, areSafeParamsEnabled } from '../utils' import { ParametersStatus, areEthereumParamsVisible, areSafeParamsEnabled, ethereumTxParametersTitle } from '../utils'
import { useSelector } from 'react-redux' import { useSelector } from 'react-redux'
import { safeThresholdSelector } from 'src/logic/safe/store/selectors' import { safeThresholdSelector } from 'src/logic/safe/store/selectors'
@ -35,8 +35,9 @@ type Props = {
onEdit: () => void onEdit: () => void
compact?: boolean compact?: boolean
parametersStatus?: ParametersStatus parametersStatus?: ParametersStatus
isTransactionExecution: boolean
isTransactionCreation: boolean isTransactionCreation: boolean
isTransactionExecution: boolean
isOffChainSignature: boolean
} }
export const TxParametersDetail = ({ export const TxParametersDetail = ({
@ -46,11 +47,12 @@ export const TxParametersDetail = ({
parametersStatus, parametersStatus,
isTransactionCreation, isTransactionCreation,
isTransactionExecution, isTransactionExecution,
isOffChainSignature,
}: Props): ReactElement | null => { }: Props): ReactElement | null => {
const threshold = useSelector(safeThresholdSelector) || 1 const threshold = useSelector(safeThresholdSelector) || 1
const defaultParameterStatus = threshold > 1 ? 'ETH_DISABLED' : 'ENABLED' const defaultParameterStatus = isOffChainSignature && threshold > 1 ? 'ETH_HIDDEN' : 'ENABLED'
if (!isTransactionExecution && !isTransactionCreation) { if (!isTransactionExecution && !isTransactionCreation && isOffChainSignature) {
return null return null
} }
@ -62,7 +64,7 @@ export const TxParametersDetail = ({
<AccordionDetails> <AccordionDetails>
<AccordionDetailsWrapper> <AccordionDetailsWrapper>
<StyledText size="md" color="placeHolder"> <StyledText size="md" color="placeHolder">
Safe transactions parameters Safe transaction
</StyledText> </StyledText>
<TxParameterWrapper> <TxParameterWrapper>
@ -95,57 +97,30 @@ export const TxParametersDetail = ({
</Text> </Text>
</TxParameterWrapper> </TxParameterWrapper>
<TxParameterWrapper> {areEthereumParamsVisible(parametersStatus || defaultParameterStatus) && (
<StyledText size="md" color="placeHolder"> <>
Ethereum transaction parameters <TxParameterWrapper>
</StyledText> <StyledText size="md" color="placeHolder">
</TxParameterWrapper> {ethereumTxParametersTitle(isTransactionExecution)}
</StyledText>
</TxParameterWrapper>
<TxParameterWrapper> <TxParameterWrapper>
<Text <Text size="lg">Nonce</Text>
size="lg" <Text size="lg">{txParameters.ethNonce}</Text>
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'} </TxParameterWrapper>
>
Ethereum nonce
</Text>
<Text
size="lg"
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'}
>
{txParameters.ethNonce}
</Text>
</TxParameterWrapper>
<TxParameterWrapper> <TxParameterWrapper>
<Text <Text size="lg">Gas limit</Text>
size="lg" <Text size="lg">{txParameters.ethGasLimit}</Text>
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'} </TxParameterWrapper>
>
Ethereum gas limit
</Text>
<Text
size="lg"
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'}
>
{txParameters.ethGasLimit}
</Text>
</TxParameterWrapper>
<TxParameterWrapper>
<Text
size="lg"
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'}
>
Ethereum gas price
</Text>
<Text
size="lg"
color={areEthereumParamsEnabled(parametersStatus || defaultParameterStatus) ? 'text' : 'secondaryLight'}
>
{txParameters.ethGasPrice}
</Text>
</TxParameterWrapper>
<TxParameterWrapper>
<Text size="lg">Gas price</Text>
<Text size="lg">{txParameters.ethGasPrice}</Text>
</TxParameterWrapper>
</>
)}
<StyledButtonLink color="primary" textSize="xl" onClick={onEdit}> <StyledButtonLink color="primary" textSize="xl" onClick={onEdit}>
Edit Edit
</StyledButtonLink> </StyledButtonLink>

View File

@ -1,8 +1,8 @@
export type ParametersStatus = 'ENABLED' | 'DISABLED' | 'SAFE_DISABLED' | 'ETH_DISABLED' | 'CANCEL_TRANSACTION' export type ParametersStatus = 'ENABLED' | 'DISABLED' | 'SAFE_DISABLED' | 'ETH_HIDDEN' | 'CANCEL_TRANSACTION'
export const areEthereumParamsEnabled = (parametersStatus: ParametersStatus): boolean => { export const areEthereumParamsVisible = (parametersStatus: ParametersStatus): boolean => {
return ( return (
parametersStatus === 'ENABLED' || (parametersStatus !== 'ETH_DISABLED' && parametersStatus !== 'CANCEL_TRANSACTION') parametersStatus === 'ENABLED' || (parametersStatus !== 'ETH_HIDDEN' && parametersStatus !== 'CANCEL_TRANSACTION')
) )
} }
@ -12,3 +12,7 @@ export const areSafeParamsEnabled = (parametersStatus: ParametersStatus): boolea
(parametersStatus !== 'SAFE_DISABLED' && parametersStatus !== 'CANCEL_TRANSACTION') (parametersStatus !== 'SAFE_DISABLED' && parametersStatus !== 'CANCEL_TRANSACTION')
) )
} }
export const ethereumTxParametersTitle = (isExecution: boolean): string => {
return `Owner transaction ${isExecution ? '(Execution)' : '(On-chain approval)'}`
}