diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx
index 3b587995..3350981c 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx
@@ -5,70 +5,41 @@ import { useField, useFormState } from 'react-final-form'
import Button from 'src/components/layout/Button'
import Row from 'src/components/layout/Row'
import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style'
-import { createTxObject } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils'
+import { isReadMethod } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils'
const useStyles = makeStyles(styles as any)
-const Buttons = ({ onCallSubmit, onClose }) => {
+const Buttons = ({ onClose }) => {
const classes = useStyles()
const {
input: { value: method },
} = useField('selectedMethod', { value: true })
- const {
- input: { value: contractAddress },
- } = useField('contractAddress', { valid: true } as any)
- const { modifiedSinceLastSubmit, submitError, submitting, valid, validating, values } = useFormState({
+ const { modifiedSinceLastSubmit, submitError, submitting, valid, validating } = useFormState({
subscription: {
modifiedSinceLastSubmit: true,
submitError: true,
submitting: true,
valid: true,
- values: true,
validating: true,
},
})
- const handleCallSubmit = async () => {
- const results = await createTxObject(method, contractAddress, values).call()
- onCallSubmit(results)
- }
-
return (
- {method && (method as any).action === 'read' ? (
-
- ) : (
-
- )}
+
)
}
diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx
index de34ffc0..2c945a0d 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx
+++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx
@@ -1,12 +1,13 @@
import { makeStyles } from '@material-ui/core/styles'
-import { FORM_ERROR } from 'final-form'
import React from 'react'
+import { useSelector } from 'react-redux'
import { styles } from './style'
import GnoForm from 'src/components/forms/GnoForm'
import Block from 'src/components/layout/Block'
import Hairline from 'src/components/layout/Hairline'
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
+import { safeSelector } from 'src/routes/safe/store/selectors'
import Buttons from './Buttons'
import ContractABI from './ContractABI'
import EthAddressInput from './EthAddressInput'
@@ -17,12 +18,14 @@ import Header from './Header'
import MethodsDropdown from './MethodsDropdown'
import RenderInputParams from './RenderInputParams'
import RenderOutputParams from './RenderOutputParams'
-import { abiExtractor, createTxObject, formMutators } from './utils'
+import { abiExtractor, createTxObject, formMutators, handleSubmitError, isReadMethod } from './utils'
const useStyles = makeStyles(styles as any)
const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }) => {
const classes = useStyles()
+ const { address: safeAddress = '' } = useSelector(safeSelector)
+ let setCallResults
React.useMemo(() => {
if (contractAddress) {
@@ -35,17 +38,18 @@ const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }
try {
const txObject = createTxObject(selectedMethod, contractAddress, values)
const data = txObject.encodeABI()
- await txObject.estimateGas()
- onNext({ contractAddress, data, selectedMethod, value, ...values })
- } catch (e) {
- for (const key in values) {
- if (values.hasOwnProperty(key) && values[key] === e.value) {
- return { [key]: e.reason }
- }
+ const result = await txObject.call({ from: safeAddress })
+
+ if (isReadMethod(selectedMethod)) {
+ setCallResults(result)
+
+ // this was a read method, so we won't go to the 'review' screen
+ return
}
- // .estimateGas() failed
- return { [FORM_ERROR]: e.message }
+ onNext({ contractAddress, data, selectedMethod, value, ...values })
+ } catch (error) {
+ return handleSubmitError(error, values)
}
}
}
@@ -62,6 +66,8 @@ const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }
subscription={{ submitting: true, pristine: true }}
>
{(submitting, validating, rest, mutators) => {
+ setCallResults = mutators.setCallResults
+
return (
<>
@@ -80,7 +86,7 @@ const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }
-
+
>
)
}}
diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts
index 4fa20b0d..2c961591 100644
--- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts
+++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts
@@ -1,3 +1,4 @@
+import { FORM_ERROR } from 'final-form'
import createDecorator from 'final-form-calculate'
import { mustBeEthereumAddress, mustBeEthereumContractAddress } from 'src/components/forms/validator'
@@ -48,6 +49,17 @@ export const formMutators = {
},
}
+export const handleSubmitError = (error, values) => {
+ for (const key in values) {
+ if (values.hasOwnProperty(key) && values[key] === error.value) {
+ return { [key]: error.reason }
+ }
+ }
+
+ // .call() failed and we're logging a generic error
+ return { [FORM_ERROR]: error.message }
+}
+
export const createTxObject = (method, contractAddress, values) => {
const web3 = getWeb3()
const contract: any = new web3.eth.Contract([method], contractAddress)
@@ -56,3 +68,5 @@ export const createTxObject = (method, contractAddress, values) => {
return contract.methods[name](...args)
}
+
+export const isReadMethod = (method: any) => method && method.action === 'read'