add types and fix `useField` usage
This commit is contained in:
parent
cd77fba5b7
commit
e3a9945675
|
@ -235,6 +235,7 @@
|
|||
"react-app-rewired": "^2.1.6",
|
||||
"truffle": "5.1.23",
|
||||
"typescript": "~3.7.2",
|
||||
"wait-on": "5.0.0"
|
||||
"wait-on": "5.0.0",
|
||||
"web3-utils": "^1.2.8"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,48 @@
|
|||
import { getWeb3 } from 'src/logic/wallets/getWeb3'
|
||||
import { ABI, ExtendedABI } from './types'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
|
||||
export const getMethodSignature = ({ inputs, name }) => {
|
||||
import { web3ReadOnly as web3 } from 'src/logic/wallets/getWeb3'
|
||||
|
||||
export interface AbiItemExtended extends AbiItem {
|
||||
action: string
|
||||
methodSignature: string
|
||||
signatureHash: string
|
||||
}
|
||||
|
||||
export const getMethodSignature = ({ inputs, name }: AbiItem) => {
|
||||
const params = inputs.map((x) => x.type).join(',')
|
||||
return `${name}(${params})`
|
||||
}
|
||||
|
||||
export const getSignatureHash = (signature) => {
|
||||
const web3 = getWeb3()
|
||||
export const getSignatureHash = (signature: string): string => {
|
||||
return web3.utils.keccak256(signature).toString()
|
||||
}
|
||||
|
||||
export const getMethodHash = (method) => {
|
||||
export const getMethodHash = (method: AbiItem): string => {
|
||||
const signature = getMethodSignature(method)
|
||||
return getSignatureHash(signature)
|
||||
}
|
||||
|
||||
export const getMethodSignatureAndSignatureHash = (method) => {
|
||||
export const getMethodSignatureAndSignatureHash = (
|
||||
method: AbiItem,
|
||||
): { methodSignature: string; signatureHash: string } => {
|
||||
const methodSignature = getMethodSignature(method)
|
||||
const signatureHash = getSignatureHash(methodSignature)
|
||||
return { methodSignature, signatureHash }
|
||||
}
|
||||
|
||||
export const extractUsefulMethods = (abi: ABI): ExtendedABI => {
|
||||
export const extractUsefulMethods = (abi: AbiItem[]): AbiItemExtended[] => {
|
||||
return abi
|
||||
.filter(({ constant, name, type }) => type === 'function' && !!name && typeof constant === 'boolean')
|
||||
.map((method) => ({
|
||||
action: method.constant ? 'read' : 'write',
|
||||
...getMethodSignatureAndSignatureHash(method),
|
||||
...method,
|
||||
}))
|
||||
.map(
|
||||
(method): AbiItemExtended => ({
|
||||
action: method.constant ? 'read' : 'write',
|
||||
...getMethodSignatureAndSignatureHash(method),
|
||||
...method,
|
||||
}),
|
||||
)
|
||||
.sort(({ name: a }, { name: b }) => (a.toLowerCase() > b.toLowerCase() ? 1 : -1))
|
||||
}
|
||||
|
||||
export const isPayable = (method) => {
|
||||
export const isPayable = (method: AbiItem | AbiItemExtended): boolean => {
|
||||
return method.payable
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
export interface InterfaceParams {
|
||||
internalType: string
|
||||
name: string
|
||||
type: string
|
||||
}
|
||||
|
||||
export interface MethodInterface {
|
||||
constant: boolean
|
||||
inputs: InterfaceParams[]
|
||||
name: string
|
||||
outputs: InterfaceParams[]
|
||||
payable: boolean
|
||||
stateMutability: string
|
||||
type: string
|
||||
}
|
||||
|
||||
export interface ExtendedContractInterface extends MethodInterface {
|
||||
action: string
|
||||
methodSignature: string
|
||||
signatureHash: string
|
||||
}
|
||||
|
||||
export type ABI = MethodInterface[]
|
||||
|
||||
export type ExtendedABI = ExtendedContractInterface[]
|
|
@ -17,7 +17,7 @@ const Buttons = ({ onClose }: ButtonProps) => {
|
|||
const classes = useStyles()
|
||||
const {
|
||||
input: { value: method },
|
||||
} = useField('selectedMethod', { value: true })
|
||||
} = useField('selectedMethod', { subscription: { value: true } })
|
||||
const { modifiedSinceLastSubmit, submitError, submitting, valid, validating } = useFormState({
|
||||
subscription: {
|
||||
modifiedSinceLastSubmit: true,
|
||||
|
|
|
@ -25,7 +25,7 @@ const EthValue = ({ onSetMax }: EthValueProps) => {
|
|||
const { ethBalance } = useSelector(safeSelector)
|
||||
const {
|
||||
input: { value: method },
|
||||
} = useField('selectedMethod', { value: true })
|
||||
} = useField('selectedMethod', { subscription: { value: true } })
|
||||
const disabled = !isPayable(method)
|
||||
|
||||
return disabled ? null : (
|
||||
|
|
|
@ -8,6 +8,7 @@ import SearchIcon from '@material-ui/icons/Search'
|
|||
import classNames from 'classnames'
|
||||
import React from 'react'
|
||||
import { useField, useFormState } from 'react-final-form'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
|
||||
import Col from 'src/components/layout/Col'
|
||||
import Row from 'src/components/layout/Row'
|
||||
|
@ -16,12 +17,11 @@ import CheckIcon from 'src/routes/safe/components/CurrencyDropdown/img/check.svg
|
|||
import { useDropdownStyles } from 'src/routes/safe/components/CurrencyDropdown/style'
|
||||
import { DropdownListTheme } from 'src/theme/mui'
|
||||
import { extractUsefulMethods } from 'src/logic/contractInteraction/sources/ABIService'
|
||||
import { MethodInterface } from 'src/logic/contractInteraction/sources/ABIService/types'
|
||||
|
||||
const MENU_WIDTH = '452px'
|
||||
|
||||
interface MethodsDropdownProps {
|
||||
onChange: (method: MethodInterface) => void
|
||||
onChange: (method: AbiItem) => void
|
||||
}
|
||||
|
||||
const MethodsDropdown = ({ onChange }: MethodsDropdownProps) => {
|
||||
|
@ -29,7 +29,7 @@ const MethodsDropdown = ({ onChange }: MethodsDropdownProps) => {
|
|||
const {
|
||||
input: { value: abi },
|
||||
meta: { valid },
|
||||
} = useField('abi', { value: true, valid: true } as any)
|
||||
} = useField('abi', { subscription: { value: true, valid: true } })
|
||||
const {
|
||||
initialValues: { selectedMethod: selectedMethodByDefault },
|
||||
} = useFormState({ subscription: { initialValues: true } })
|
||||
|
@ -61,7 +61,7 @@ const MethodsDropdown = ({ onChange }: MethodsDropdownProps) => {
|
|||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const onMethodSelectedChanged = (chosenMethod: MethodInterface) => {
|
||||
const onMethodSelectedChanged = (chosenMethod: AbiItem) => {
|
||||
setSelectedMethod(chosenMethod)
|
||||
onChange(chosenMethod)
|
||||
handleClose()
|
||||
|
|
|
@ -10,10 +10,10 @@ import Row from 'src/components/layout/Row'
|
|||
const RenderInputParams = () => {
|
||||
const {
|
||||
meta: { valid: validABI },
|
||||
} = useField('abi', { value: true })
|
||||
} = useField('abi', { subscription: { valid: true, value: true } })
|
||||
const {
|
||||
input: { value: method },
|
||||
}: any = useField('selectedMethod', { value: true })
|
||||
}: any = useField('selectedMethod', { subscription: { value: true } })
|
||||
const renderInputs = validABI && !!method && method.inputs.length
|
||||
|
||||
return !renderInputs
|
||||
|
|
|
@ -9,10 +9,10 @@ import Row from 'src/components/layout/Row'
|
|||
const RenderOutputParams = () => {
|
||||
const {
|
||||
input: { value: method },
|
||||
}: any = useField('selectedMethod', { value: true })
|
||||
}: any = useField('selectedMethod', { subscription: { value: true } })
|
||||
const {
|
||||
input: { value: results },
|
||||
}: any = useField('callResults', { value: true })
|
||||
}: any = useField('callResults', { subscription: { value: true } })
|
||||
const multipleResults = !!method && method.outputs.length > 1
|
||||
|
||||
return results ? (
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { FORM_ERROR } from 'final-form'
|
||||
import createDecorator from 'final-form-calculate'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
|
||||
import { mustBeEthereumAddress, mustBeEthereumContractAddress } from 'src/components/forms/validator'
|
||||
import { getNetwork } from 'src/config'
|
||||
import { getConfiguredSource } from 'src/logic/contractInteraction/sources'
|
||||
import { AbiItemExtended } from 'src/logic/contractInteraction/sources/ABIService'
|
||||
import { getWeb3 } from 'src/logic/wallets/getWeb3'
|
||||
|
||||
export const NO_CONTRACT = 'no contract'
|
||||
|
@ -60,7 +62,7 @@ export const handleSubmitError = (error, values) => {
|
|||
return { [FORM_ERROR]: error.message }
|
||||
}
|
||||
|
||||
export const createTxObject = (method, contractAddress, values) => {
|
||||
export const createTxObject = (method: AbiItem, contractAddress: string, values) => {
|
||||
const web3 = getWeb3()
|
||||
const contract: any = new web3.eth.Contract([method], contractAddress)
|
||||
const { inputs, name } = method
|
||||
|
@ -69,4 +71,4 @@ export const createTxObject = (method, contractAddress, values) => {
|
|||
return contract.methods[name](...args)
|
||||
}
|
||||
|
||||
export const isReadMethod = (method: any) => method && method.action === 'read'
|
||||
export const isReadMethod = (method: AbiItemExtended): boolean => method && method.action === 'read'
|
||||
|
|
|
@ -17146,7 +17146,7 @@ web3-utils@1.2.1:
|
|||
underscore "1.9.1"
|
||||
utf8 "3.0.0"
|
||||
|
||||
web3-utils@1.2.8, web3-utils@^1.2.7:
|
||||
web3-utils@1.2.8, web3-utils@^1.2.7, web3-utils@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.8.tgz#5321d91715cd4c0869005705a33c4c042a532b18"
|
||||
integrity sha512-9SIVGFLajwlmo5joC4DGxuy2OeDkRCXVWT8JWcDQ+BayNVHyAWGvn0oGkQ0ys14Un0KK6bjjKoD0xYs4k+FaVw==
|
||||
|
|
Loading…
Reference in New Issue