Fix value bug + preserve values when changing switch
This commit is contained in:
parent
473977723b
commit
45ca501c60
|
@ -30,7 +30,7 @@ export const required = (value?: string) => {
|
||||||
export const mustBeInteger = (value: string) =>
|
export const mustBeInteger = (value: string) =>
|
||||||
!Number.isInteger(Number(value)) || value.includes('.') ? 'Must be an integer' : undefined
|
!Number.isInteger(Number(value)) || value.includes('.') ? 'Must be an integer' : undefined
|
||||||
|
|
||||||
export const mustBeFloat = (value: string) => (value && Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
|
export const mustBeFloat = (value: string) => (value && Number.isNaN(Number(value)) ? 'Must be a number' : undefined)
|
||||||
|
|
||||||
export const greaterThan = (min: number | string) => (value: string) => {
|
export const greaterThan = (min: number | string) => (value: string) => {
|
||||||
if (Number.isNaN(Number(value)) || Number.parseFloat(value) > Number(min)) {
|
if (Number.isNaN(Number(value)) || Number.parseFloat(value) > Number(min)) {
|
||||||
|
|
|
@ -59,14 +59,14 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select
|
||||||
setTx(txInfo)
|
setTx(txInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleContractInteractionCreation = (contractInteractionInfo) => {
|
const handleContractInteractionCreation = (contractInteractionInfo, submit) => {
|
||||||
setTx(contractInteractionInfo)
|
setTx(contractInteractionInfo)
|
||||||
setActiveScreen('contractInteractionReview')
|
if (submit) setActiveScreen('contractInteractionReview')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCustomTxCreation = (customTxInfo) => {
|
const handleCustomTxCreation = (customTxInfo, submit) => {
|
||||||
setActiveScreen('reviewCustomTx')
|
|
||||||
setTx(customTxInfo)
|
setTx(customTxInfo)
|
||||||
|
if (submit) setActiveScreen('reviewCustomTx')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSendCollectible = (txInfo) => {
|
const handleSendCollectible = (txInfo) => {
|
||||||
|
@ -128,7 +128,7 @@ const SendModal = ({ activeScreenType, isOpen, onClose, recipientAddress, select
|
||||||
switchMethod={handleSwitchMethod}
|
switchMethod={handleSwitchMethod}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onNext={handleCustomTxCreation}
|
onNext={handleCustomTxCreation}
|
||||||
recipientAddress={recipientAddress}
|
contractAddress={recipientAddress}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{activeScreen === 'reviewCustomTx' && (
|
{activeScreen === 'reviewCustomTx' && (
|
||||||
|
|
|
@ -33,7 +33,7 @@ import { sm } from 'src/theme/variables'
|
||||||
type Props = {
|
type Props = {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onPrev: () => void
|
onPrev: () => void
|
||||||
tx: { recipientAddress?: string; data?: string; value?: string }
|
tx: { contractAddress?: string; data?: string; value?: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
@ -52,7 +52,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props) => {
|
||||||
const { fromWei, toBN } = getWeb3().utils
|
const { fromWei, toBN } = getWeb3().utils
|
||||||
const txData = tx.data ? tx.data.trim() : ''
|
const txData = tx.data ? tx.data.trim() : ''
|
||||||
|
|
||||||
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, tx.recipientAddress, txData)
|
const estimatedGasCosts = await estimateTxGasCosts(safeAddress, tx.contractAddress, txData)
|
||||||
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether')
|
||||||
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
const formattedGasCosts = formatAmount(gasCostsAsEth)
|
||||||
|
|
||||||
|
@ -66,11 +66,11 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props) => {
|
||||||
return () => {
|
return () => {
|
||||||
isCurrent = false
|
isCurrent = false
|
||||||
}
|
}
|
||||||
}, [safeAddress, tx.data, tx.recipientAddress])
|
}, [safeAddress, tx.data, tx.contractAddress])
|
||||||
|
|
||||||
const submitTx = async () => {
|
const submitTx = async () => {
|
||||||
const web3 = getWeb3()
|
const web3 = getWeb3()
|
||||||
const txRecipient = tx.recipientAddress
|
const txRecipient = tx.contractAddress
|
||||||
const txData = tx.data ? tx.data.trim() : ''
|
const txData = tx.data ? tx.data.trim() : ''
|
||||||
const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0'
|
const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0'
|
||||||
|
|
||||||
|
@ -118,15 +118,15 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props) => {
|
||||||
</Row>
|
</Row>
|
||||||
<Row align="center" margin="md">
|
<Row align="center" margin="md">
|
||||||
<Col xs={1}>
|
<Col xs={1}>
|
||||||
<Identicon address={tx.recipientAddress} diameter={32} />
|
<Identicon address={tx.contractAddress} diameter={32} />
|
||||||
</Col>
|
</Col>
|
||||||
<Col layout="column" xs={11}>
|
<Col layout="column" xs={11}>
|
||||||
<Block justify="left">
|
<Block justify="left">
|
||||||
<Paragraph noMargin weight="bolder">
|
<Paragraph noMargin weight="bolder">
|
||||||
{tx.recipientAddress}
|
{tx.contractAddress}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
<CopyBtn content={tx.recipientAddress} />
|
<CopyBtn content={tx.contractAddress} />
|
||||||
<EtherscanBtn type="address" value={tx.recipientAddress} />
|
<EtherscanBtn type="address" value={tx.contractAddress} />
|
||||||
</Block>
|
</Block>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -19,7 +19,7 @@ import Field from 'src/components/forms/Field'
|
||||||
import GnoForm from 'src/components/forms/GnoForm'
|
import GnoForm from 'src/components/forms/GnoForm'
|
||||||
import TextField from 'src/components/forms/TextField'
|
import TextField from 'src/components/forms/TextField'
|
||||||
import TextareaField from 'src/components/forms/TextareaField'
|
import TextareaField from 'src/components/forms/TextareaField'
|
||||||
import { composeValidators, maxValue, mustBeFloat } from 'src/components/forms/validator'
|
import { composeValidators, maxValue, mustBeFloat, greaterThan } from 'src/components/forms/validator'
|
||||||
import Block from 'src/components/layout/Block'
|
import Block from 'src/components/layout/Block'
|
||||||
import Button from 'src/components/layout/Button'
|
import Button from 'src/components/layout/Button'
|
||||||
import ButtonLink from 'src/components/layout/ButtonLink'
|
import ButtonLink from 'src/components/layout/ButtonLink'
|
||||||
|
@ -34,12 +34,12 @@ import { safeSelector } from 'src/routes/safe/store/selectors'
|
||||||
import { sm } from 'src/theme/variables'
|
import { sm } from 'src/theme/variables'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
initialValues: { contractAddress?: string; recipientAddress?: string }
|
initialValues: { contractAddress?: string }
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onNext: (any) => void
|
onNext: (any, submit: boolean) => void
|
||||||
isABI: boolean
|
isABI: boolean
|
||||||
switchMethod: () => void
|
switchMethod: () => void
|
||||||
recipientAddress: string
|
contractAddress: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
|
@ -48,7 +48,7 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
initialValues,
|
initialValues,
|
||||||
onClose,
|
onClose,
|
||||||
onNext,
|
onNext,
|
||||||
recipientAddress,
|
contractAddress,
|
||||||
switchMethod,
|
switchMethod,
|
||||||
isABI,
|
isABI,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
@ -56,7 +56,7 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
const { ethBalance } = useSelector(safeSelector)
|
const { ethBalance } = useSelector(safeSelector)
|
||||||
const [qrModalOpen, setQrModalOpen] = useState<boolean>(false)
|
const [qrModalOpen, setQrModalOpen] = useState<boolean>(false)
|
||||||
const [selectedEntry, setSelectedEntry] = useState<{ address?: string; name?: string } | null>({
|
const [selectedEntry, setSelectedEntry] = useState<{ address?: string; name?: string } | null>({
|
||||||
address: recipientAddress || initialValues.recipientAddress,
|
address: contractAddress || initialValues.contractAddress,
|
||||||
name: '',
|
name: '',
|
||||||
})
|
})
|
||||||
const [pristine, setPristine] = useState<boolean>(true)
|
const [pristine, setPristine] = useState<boolean>(true)
|
||||||
|
@ -68,9 +68,14 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
}
|
}
|
||||||
}, [selectedEntry, pristine])
|
}, [selectedEntry, pristine])
|
||||||
|
|
||||||
const handleSubmit = (values: any) => {
|
const saveForm = async (values) => {
|
||||||
|
await handleSubmit(values, false)
|
||||||
|
switchMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = (values: any, submit = true) => {
|
||||||
if (values.data || values.value) {
|
if (values.data || values.value) {
|
||||||
onNext(values)
|
onNext(values, submit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +92,7 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
utils.changeValue(state, 'value', () => ethBalance)
|
utils.changeValue(state, 'value', () => ethBalance)
|
||||||
},
|
},
|
||||||
setRecipient: (args, state, utils) => {
|
setRecipient: (args, state, utils) => {
|
||||||
utils.changeValue(state, 'recipientAddress', () => args[0])
|
utils.changeValue(state, 'contractAddress', () => args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +111,6 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
<GnoForm formMutators={formMutators} initialValues={initialValues} onSubmit={handleSubmit}>
|
<GnoForm formMutators={formMutators} initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
{(...args) => {
|
{(...args) => {
|
||||||
const mutators = args[3]
|
const mutators = args[3]
|
||||||
|
|
||||||
let shouldDisableSubmitButton = !isValidAddress
|
let shouldDisableSubmitButton = !isValidAddress
|
||||||
if (selectedEntry) {
|
if (selectedEntry) {
|
||||||
shouldDisableSubmitButton = !selectedEntry.address
|
shouldDisableSubmitButton = !selectedEntry.address
|
||||||
|
@ -228,7 +232,7 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
placeholder="Value*"
|
placeholder="Value*"
|
||||||
text="Value*"
|
text="Value*"
|
||||||
type="text"
|
type="text"
|
||||||
validate={composeValidators(mustBeFloat, maxValue(ethBalance))}
|
validate={composeValidators(mustBeFloat, maxValue(ethBalance), greaterThan(0))}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -244,7 +248,7 @@ const SendCustomTx: React.FC<Props> = ({
|
||||||
</Row>
|
</Row>
|
||||||
<Paragraph color="disabled" noMargin size="md" style={{ letterSpacing: '-0.5px' }}>
|
<Paragraph color="disabled" noMargin size="md" style={{ letterSpacing: '-0.5px' }}>
|
||||||
Use custom data (hex encoded)
|
Use custom data (hex encoded)
|
||||||
<Switch checked={!isABI} onChange={switchMethod} />
|
<Switch onChange={() => saveForm(args[2].values)} checked={!isABI} />
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Block>
|
</Block>
|
||||||
<Hairline />
|
<Hairline />
|
||||||
|
|
|
@ -37,7 +37,7 @@ export interface ContractInteractionProps {
|
||||||
isABI: boolean
|
isABI: boolean
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
switchMethod: () => void
|
switchMethod: () => void
|
||||||
onNext: (tx: CreatedTx) => void
|
onNext: (tx: CreatedTx, submit: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
||||||
|
@ -58,13 +58,18 @@ const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
||||||
}
|
}
|
||||||
}, [contractAddress, initialValues.contractAddress])
|
}, [contractAddress, initialValues.contractAddress])
|
||||||
|
|
||||||
const handleSubmit = async ({ contractAddress, selectedMethod, value, ...values }) => {
|
const saveForm = async (values) => {
|
||||||
|
await handleSubmit(values, false)
|
||||||
|
switchMethod()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async ({ contractAddress, selectedMethod, value, ...values }, submit = true) => {
|
||||||
if (value || (contractAddress && selectedMethod)) {
|
if (value || (contractAddress && selectedMethod)) {
|
||||||
try {
|
try {
|
||||||
const txObject = createTxObject(selectedMethod, contractAddress, values)
|
const txObject = createTxObject(selectedMethod, contractAddress, values)
|
||||||
const data = txObject.encodeABI()
|
const data = txObject.encodeABI()
|
||||||
|
|
||||||
if (isReadMethod(selectedMethod)) {
|
if (isReadMethod(selectedMethod) && submit) {
|
||||||
const result = await txObject.call({ from: safeAddress })
|
const result = await txObject.call({ from: safeAddress })
|
||||||
setCallResults(result)
|
setCallResults(result)
|
||||||
|
|
||||||
|
@ -72,7 +77,7 @@ const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
onNext({ ...values, contractAddress, data, selectedMethod, value })
|
onNext({ ...values, contractAddress, data, selectedMethod, value }, submit)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return handleSubmitError(error, values)
|
return handleSubmitError(error, values)
|
||||||
}
|
}
|
||||||
|
@ -88,7 +93,7 @@ const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
||||||
formMutators={formMutators}
|
formMutators={formMutators}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
subscription={{ submitting: true, pristine: true }}
|
subscription={{ submitting: true, pristine: true, values: true }}
|
||||||
>
|
>
|
||||||
{(submitting, validating, rest, mutators) => {
|
{(submitting, validating, rest, mutators) => {
|
||||||
setCallResults = mutators.setCallResults
|
setCallResults = mutators.setCallResults
|
||||||
|
@ -111,7 +116,7 @@ const ContractInteraction: React.FC<ContractInteractionProps> = ({
|
||||||
<FormErrorMessage />
|
<FormErrorMessage />
|
||||||
<Paragraph color="disabled" noMargin size="md" style={{ letterSpacing: '-0.5px' }}>
|
<Paragraph color="disabled" noMargin size="md" style={{ letterSpacing: '-0.5px' }}>
|
||||||
Use custom data (hex encoded)
|
Use custom data (hex encoded)
|
||||||
<Switch checked={!isABI} onChange={switchMethod} />
|
<Switch checked={!isABI} onChange={() => saveForm(rest.values)} />
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Block>
|
</Block>
|
||||||
<Hairline />
|
<Hairline />
|
||||||
|
|
Loading…
Reference in New Issue