From 6d2638410f4178bc2139a48685bfdb559b47899b Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Tue, 23 Jun 2020 10:36:30 -0300 Subject: [PATCH 1/7] Set address book suggestions --- .../screens/AddressBookInput/index.tsx | 2 +- .../EthAddressInput/index.tsx | 47 ++++++++++++++----- .../screens/ContractInteraction/index.tsx | 3 +- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx index e3a50f57..0a7d416a 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx @@ -50,7 +50,7 @@ const AddressBookInput = ({ }: any) => { const addressBook = useSelector(getAddressBookListSelector) const [isValidForm, setIsValidForm] = useState(true) - const [validationText, setValidationText] = useState(true) + const [validationText, setValidationText] = useState('') const [inputTouched, setInputTouched] = useState(false) const [blurred, setBlurred] = useState(pristine) const [adbkList, setADBKList] = useState(List([])) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx index 91ddf4df..a4cef3f1 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx @@ -1,7 +1,8 @@ import { makeStyles } from '@material-ui/core/styles' -import React from 'react' +import React, { useState } from 'react' import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' +import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' import Field from 'src/components/forms/Field' import TextField from 'src/components/forms/TextField' import { @@ -22,12 +23,26 @@ export interface EthAddressProps { name: string onScannedValue: (scannedValue: string) => void text: string + value?: string + pristine: boolean } -const EthAddressInput = ({ isContract = true, isRequired = true, name, onScannedValue, text }: EthAddressProps) => { +const EthAddressInput = ({ + isContract = true, + isRequired = true, + name, + onScannedValue, + text, + value, + pristine, +}: EthAddressProps) => { const classes = useStyles() const validatorsList = [isRequired && required, mustBeEthereumAddress, isContract && mustBeEthereumContractAddress] const validate = composeValidators(...validatorsList.filter((_) => _)) + const [selectedEntry, setSelectedEntry] = useState<{ address?: string; name?: string } | null>({ + address: value, + name: '', + }) const handleScan = (value, closeQrModal) => { let scannedAddress = value @@ -44,15 +59,25 @@ const EthAddressInput = ({ isContract = true, isRequired = true, name, onScanned <> - + {selectedEntry && selectedEntry.address ? ( + + ) : ( + {}} + fieldMutator={onScannedValue} + isCustomTx + pristine={pristine} + /> + )} 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 2c4b94a8..d6caadfc 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx @@ -100,15 +100,16 @@ const ContractInteraction: React.FC = ({ > {(submitting, validating, rest, mutators) => { setCallResults = mutators.setCallResults - return ( <> From 62270e180b8861759e14f8cb846aa7a86ae2db25 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Wed, 24 Jun 2020 16:39:19 -0300 Subject: [PATCH 2/7] update types --- .../screens/AddressBookInput/index.tsx | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx index 0a7d416a..50ef42f2 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx @@ -14,6 +14,17 @@ import { getAddressBookListSelector } from 'src/logic/addressBook/store/selector import { getAddressFromENS } from 'src/logic/wallets/getWeb3' import { isValidEnsName } from 'src/logic/wallets/ethAddresses' +export interface AddressBookProps { + classes: any + fieldMutator + isCustomTx: boolean + pristine: boolean + recipientAddress: string + setIsValidAddress: string + setSelectedEntry: string + onScannedValue: (scannedValue: string) => void +} + const textFieldLabelStyle = makeStyles(() => ({ root: { overflow: 'hidden', @@ -30,13 +41,15 @@ const textFieldInputStyle = makeStyles(() => ({ }, })) -const filterAddressBookWithContractAddresses = async (addressBook) => { +const filterAddressBookWithContractAddresses = async (addressBook: Array): Promise => { const abFlags = await Promise.all( - addressBook.map(async ({ address }) => { - return (await mustBeEthereumContractAddress(address)) === undefined - }), + addressBook.map( + async ({ address }: { address: string }): Promise => { + return (await mustBeEthereumContractAddress(address)) === undefined + }, + ), ) - return addressBook.filter((adbkEntry, index) => abFlags[index]) + return addressBook.filter((_, index) => abFlags[index]) } const AddressBookInput = ({ @@ -57,7 +70,7 @@ const AddressBookInput = ({ const [inputAddValue, setInputAddValue] = useState(recipientAddress) - const onAddressInputChanged = async (addressValue) => { + const onAddressInputChanged = async (addressValue: string): Promise => { setInputAddValue(addressValue) let resolvedAddress = addressValue let isValidText @@ -96,7 +109,7 @@ const AddressBookInput = ({ } useEffect(() => { - const filterAdbkContractAddresses = async () => { + const filterAdbkContractAddresses = async (): Promise => { if (!isCustomTx) { setADBKList(addressBook) return From 79fbc2a54bd1b4e0f2ca8cf30e366eeeb014c6ad Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Wed, 24 Jun 2020 16:57:45 -0300 Subject: [PATCH 3/7] Add types for Address book suggestion --- .../SendModal/screens/AddressBookInput/index.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx index 313af8e4..5923cd7c 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx @@ -16,13 +16,12 @@ import { isValidEnsName } from 'src/logic/wallets/ethAddresses' export interface AddressBookProps { classes: any - fieldMutator - isCustomTx: boolean + fieldMutator: (address: string) => void + isCustomTx?: boolean pristine: boolean - recipientAddress: string - setIsValidAddress: string - setSelectedEntry: string - onScannedValue: (scannedValue: string) => void + recipientAddress?: string + setSelectedEntry: (entry?: any) => void + setIsValidAddress: (valid?: boolean) => void } const textFieldLabelStyle = makeStyles(() => ({ @@ -60,7 +59,7 @@ const AddressBookInput = ({ recipientAddress, setIsValidAddress, setSelectedEntry, -}: any) => { +}: AddressBookProps) => { const addressBook = useSelector(getAddressBookListSelector) const [isValidForm, setIsValidForm] = useState(true) const [validationText, setValidationText] = useState('') From d11142de709f5b65d5ef6405af5bf23fcaa536b2 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Thu, 25 Jun 2020 21:22:17 -0300 Subject: [PATCH 4/7] Update types --- .../Balances/SendModal/screens/AddressBookInput/index.tsx | 4 +++- yarn.lock | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx index 5923cd7c..94cf2b62 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx @@ -20,7 +20,9 @@ export interface AddressBookProps { isCustomTx?: boolean pristine: boolean recipientAddress?: string - setSelectedEntry: (entry?: any) => void + setSelectedEntry: ( + entry: { address?: string; name?: string } | React.SetStateAction<{ address: any; name: string }>, + ) => void setIsValidAddress: (valid?: boolean) => void } diff --git a/yarn.lock b/yarn.lock index 0bc94691..1e7f3d99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17263,9 +17263,9 @@ web3-provider-engine@^15.0.4: xhr "^2.2.0" xtend "^4.0.1" -"web3-provider-engine@git+https://github.com/trufflesuite/provider-engine.git#web3-one": +"web3-provider-engine@https://github.com/trufflesuite/provider-engine#web3-one": version "14.0.6" - resolved "git+https://github.com/trufflesuite/provider-engine.git#9694f5b4e5500651bd2ff689df8529bb5cf6b96f" + resolved "https://github.com/trufflesuite/provider-engine#9694f5b4e5500651bd2ff689df8529bb5cf6b96f" dependencies: async "^2.5.0" backoff "^2.5.0" From 89100d5158f2f96600981832500a91d6f8181138 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 26 Jun 2020 13:04:43 -0300 Subject: [PATCH 5/7] Change value validator --- src/components/forms/validator.ts | 8 ++++++++ .../screens/ContractInteraction/SendCustomTx/index.tsx | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/forms/validator.ts b/src/components/forms/validator.ts index ecd3d604..2f5e052e 100644 --- a/src/components/forms/validator.ts +++ b/src/components/forms/validator.ts @@ -40,6 +40,14 @@ export const greaterThan = (min: number | string) => (value: string) => { return `Should be greater than ${min}` } +export const equalOrGreaterThan = (min: number | string) => (value: string) => { + if (Number.isNaN(Number(value)) || Number.parseFloat(value) >= Number(min)) { + return undefined + } + + return `Should be equal or greater than ${min}` +} + const regexQuery = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i const url = new RegExp(regexQuery) export const mustBeUrl = (value: string) => { diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx index 69c172d4..a222e961 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx @@ -19,7 +19,7 @@ import Field from 'src/components/forms/Field' import GnoForm from 'src/components/forms/GnoForm' import TextField from 'src/components/forms/TextField' import TextareaField from 'src/components/forms/TextareaField' -import { composeValidators, maxValue, mustBeFloat, greaterThan } from 'src/components/forms/validator' +import { composeValidators, maxValue, mustBeFloat, equalOrGreaterThan } from 'src/components/forms/validator' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' import ButtonLink from 'src/components/layout/ButtonLink' @@ -230,7 +230,7 @@ const SendCustomTx: React.FC = ({ initialValues, onClose, onNext, contrac placeholder="Value*" text="Value*" type="text" - validate={composeValidators(mustBeFloat, maxValue(ethBalance), greaterThan(0))} + validate={composeValidators(mustBeFloat, maxValue(ethBalance), equalOrGreaterThan(0))} /> From 0587bb91390cf5e54425b54b9eed508c8392dd8f Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Mon, 29 Jun 2020 13:48:46 -0300 Subject: [PATCH 6/7] Fix types + improve form values --- src/components/forms/validator.ts | 2 +- .../SendModal/screens/AddressBookInput/index.tsx | 16 ++++++++++------ .../SendModal/screens/AddressBookInput/style.ts | 4 +++- .../EthAddressInput/index.tsx | 15 ++++++++------- .../screens/ContractInteraction/index.tsx | 2 -- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/components/forms/validator.ts b/src/components/forms/validator.ts index 2f5e052e..8cf59811 100644 --- a/src/components/forms/validator.ts +++ b/src/components/forms/validator.ts @@ -40,7 +40,7 @@ export const greaterThan = (min: number | string) => (value: string) => { return `Should be greater than ${min}` } -export const equalOrGreaterThan = (min: number | string) => (value: string) => { +export const equalOrGreaterThan = (min: number | string) => (value: string): undefined | string => { if (Number.isNaN(Number(value)) || Number.parseFloat(value) >= Number(min)) { return undefined } diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx index 94cf2b62..fc6915ae 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.tsx @@ -15,17 +15,18 @@ import { getAddressFromENS } from 'src/logic/wallets/getWeb3' import { isValidEnsName } from 'src/logic/wallets/ethAddresses' export interface AddressBookProps { - classes: any fieldMutator: (address: string) => void isCustomTx?: boolean pristine: boolean recipientAddress?: string setSelectedEntry: ( - entry: { address?: string; name?: string } | React.SetStateAction<{ address: any; name: string }>, + entry: { address?: string; name?: string } | React.SetStateAction<{ address: string; name: string }>, ) => void setIsValidAddress: (valid?: boolean) => void } +const useStyles = makeStyles(styles) + const textFieldLabelStyle = makeStyles(() => ({ root: { overflow: 'hidden', @@ -42,7 +43,9 @@ const textFieldInputStyle = makeStyles(() => ({ }, })) -const filterAddressBookWithContractAddresses = async (addressBook: Array): Promise => { +const filterAddressBookWithContractAddresses = async ( + addressBook: List<{ address: string }>, +): Promise> => { const abFlags = await Promise.all( addressBook.map( async ({ address }: { address: string }): Promise => { @@ -50,11 +53,11 @@ const filterAddressBookWithContractAddresses = async (addressBook: Array): }, ), ) + return addressBook.filter((_, index) => abFlags[index]) } const AddressBookInput = ({ - classes, fieldMutator, isCustomTx, pristine, @@ -62,12 +65,13 @@ const AddressBookInput = ({ setIsValidAddress, setSelectedEntry, }: AddressBookProps) => { + const classes = useStyles() const addressBook = useSelector(getAddressBookListSelector) const [isValidForm, setIsValidForm] = useState(true) - const [validationText, setValidationText] = useState('') + const [validationText, setValidationText] = useState('') const [inputTouched, setInputTouched] = useState(false) const [blurred, setBlurred] = useState(pristine) - const [adbkList, setADBKList] = useState(List([])) + const [adbkList, setADBKList] = useState>(List([])) const [inputAddValue, setInputAddValue] = useState(recipientAddress) diff --git a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/style.ts b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/style.ts index b7468d06..b6d2d076 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/style.ts +++ b/src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/style.ts @@ -1,4 +1,6 @@ -export const styles = () => ({ +import { createStyles } from '@material-ui/core' + +export const styles = createStyles({ itemOptionList: { display: 'flex', }, diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx index a4cef3f1..d846772f 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx @@ -1,5 +1,6 @@ import { makeStyles } from '@material-ui/core/styles' import React, { useState } from 'react' +import { useFormState, useField } from 'react-final-form' import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' @@ -17,14 +18,12 @@ import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/Co const useStyles = makeStyles(styles) -export interface EthAddressProps { +export interface AddressBookInputProps { isContract?: boolean isRequired?: boolean name: string onScannedValue: (scannedValue: string) => void text: string - value?: string - pristine: boolean } const EthAddressInput = ({ @@ -33,12 +32,14 @@ const EthAddressInput = ({ name, onScannedValue, text, - value, - pristine, -}: EthAddressProps) => { +}: AddressBookInputProps) => { const classes = useStyles() const validatorsList = [isRequired && required, mustBeEthereumAddress, isContract && mustBeEthereumContractAddress] const validate = composeValidators(...validatorsList.filter((_) => _)) + const { pristine } = useFormState({ subscription: { pristine: true } }) + const { + input: { value }, + } = useField('contractAddress', { subscription: { value: true } }) const [selectedEntry, setSelectedEntry] = useState<{ address?: string; name?: string } | null>({ address: value, name: '', @@ -59,7 +60,7 @@ const EthAddressInput = ({ <> - {selectedEntry && selectedEntry.address ? ( + {selectedEntry?.address ? ( = ({ From 72a13f8c74a8778aa3f912a0acd2593edb1f0f92 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 3 Jul 2020 14:48:18 -0300 Subject: [PATCH 7/7] Update name in props --- .../screens/ContractInteraction/EthAddressInput/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx index d846772f..0c11b16e 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput/index.tsx @@ -18,7 +18,7 @@ import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/Co const useStyles = makeStyles(styles) -export interface AddressBookInputProps { +export interface EthAddressInputProps { isContract?: boolean isRequired?: boolean name: string @@ -32,7 +32,7 @@ const EthAddressInput = ({ name, onScannedValue, text, -}: AddressBookInputProps) => { +}: EthAddressInputProps) => { const classes = useStyles() const validatorsList = [isRequired && required, mustBeEthereumAddress, isContract && mustBeEthereumContractAddress] const validate = composeValidators(...validatorsList.filter((_) => _))