Commit ca47d79c authored by tom's avatar tom

contract libraries

parent e52f2ea9
...@@ -11,7 +11,7 @@ interface Props { ...@@ -11,7 +11,7 @@ interface Props {
control: Control<FormFields>; control: Control<FormFields>;
} }
const ContractVerificationFieldIsConstArgs = ({ control }: Props) => { const ContractVerificationFieldConstArgs = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'constructor_args'>}) => ( const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'constructor_args'>}) => (
<CheckboxInput<FormFields, 'constructor_args'> text="Try to fetch constructor arguments automatically" field={ field }/> <CheckboxInput<FormFields, 'constructor_args'> text="Try to fetch constructor arguments automatically" field={ field }/>
), []); ), []);
...@@ -30,4 +30,4 @@ const ContractVerificationFieldIsConstArgs = ({ control }: Props) => { ...@@ -30,4 +30,4 @@ const ContractVerificationFieldIsConstArgs = ({ control }: Props) => {
); );
}; };
export default React.memo(ContractVerificationFieldIsConstArgs); export default React.memo(ContractVerificationFieldConstArgs);
...@@ -15,7 +15,7 @@ interface Props { ...@@ -15,7 +15,7 @@ interface Props {
control: Control<FormFields>; control: Control<FormFields>;
} }
const ContractVerificationEvmVersion = ({ control }: Props) => { const ContractVerificationFieldEvmVersion = ({ control }: Props) => {
const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'evm_version'>}) => { const renderControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, 'evm_version'>}) => {
return ( return (
<Select <Select
...@@ -46,4 +46,4 @@ const ContractVerificationEvmVersion = ({ control }: Props) => { ...@@ -46,4 +46,4 @@ const ContractVerificationEvmVersion = ({ control }: Props) => {
); );
}; };
export default React.memo(ContractVerificationEvmVersion); export default React.memo(ContractVerificationFieldEvmVersion);
import { Checkbox, GridItem } from '@chakra-ui/react';
import React from 'react';
import type { Control } from 'react-hook-form';
import { useFieldArray } from 'react-hook-form';
import type { FormFields } from '../types';
import ContractVerificationFieldLibraryItem from './ContractVerificationFieldLibraryItem';
interface Props {
control: Control<FormFields>;
}
const ContractVerificationFieldLibraries = ({ control }: Props) => {
const [ isEnabled, setIsEnabled ] = React.useState(false);
const { fields, append, remove, insert } = useFieldArray({
name: 'libraries',
control,
});
const handleCheckboxChange = React.useCallback(() => {
if (!isEnabled) {
append({ name: '', address: '' });
} else {
remove();
}
setIsEnabled(prev => !prev);
}, [ append, isEnabled, remove ]);
const handleAddFieldClick = React.useCallback((index: number) => {
insert(index + 1, { name: '', address: '' });
}, [ insert ]);
const handleRemoveFieldClick = React.useCallback((index: number) => {
remove(index);
}, [ remove ]);
return (
<>
<GridItem mt={ 12 }>
<Checkbox
size="lg"
onChange={ handleCheckboxChange }
>
Add contract libraries
</Checkbox>
</GridItem>
<GridItem/>
{ fields.map((field, index) => (
<ContractVerificationFieldLibraryItem
key={ field.id }
index={ index }
control={ control }
fieldsLength={ fields.length }
onAddFieldClick={ handleAddFieldClick }
onRemoveFieldClick={ handleRemoveFieldClick }
/>
)) }
</>
);
};
export default React.memo(ContractVerificationFieldLibraries);
import { Flex, FormControl, GridItem, Icon, IconButton, Input, Text } from '@chakra-ui/react';
import React from 'react';
import type { Control, ControllerRenderProps } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import minusIcon from 'icons/minus.svg';
import plusIcon from 'icons/plus.svg';
import { ADDRESS_REGEXP } from 'lib/validations/address';
import InputPlaceholder from 'ui/shared/InputPlaceholder';
const LIMIT = 10;
interface Props {
control: Control<FormFields>;
index: number;
fieldsLength: number;
onAddFieldClick: (index: number) => void;
onRemoveFieldClick: (index: number) => void;
}
const ContractVerificationFieldLibraryItem = ({ control, index, fieldsLength, onAddFieldClick, onRemoveFieldClick }: Props) => {
const ref = React.useRef<HTMLDivElement>(null);
const renderNameControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.name`>}) => {
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Input
{ ...field }
required
maxLength={ 255 }
/>
<InputPlaceholder text="Library name (.sol file)"/>
</FormControl>
);
}, []);
const renderAddressControl = React.useCallback(({ field }: {field: ControllerRenderProps<FormFields, `libraries.${ number }.address`>}) => {
return (
<FormControl variant="floating" id={ field.name } isRequired size={{ base: 'md', lg: 'lg' }}>
<Input
{ ...field }
required
/>
<InputPlaceholder text="Library address (0x...)"/>
</FormControl>
);
}, []);
const handleAddButtonClick = React.useCallback(() => {
onAddFieldClick(index);
}, [ index, onAddFieldClick ]);
const handleRemoveButtonClick = React.useCallback(() => {
onRemoveFieldClick(index);
}, [ index, onRemoveFieldClick ]);
React.useEffect(() => {
ref.current?.scrollIntoView({ behavior: 'smooth' });
}, []);
return (
<>
<GridItem mt={ index !== 0 ? 12 : 0 } ref={ ref }>
<Flex alignItems="center" justifyContent="space-between">
<Text variant="secondary" fontSize="sm">Contract library { index + 1 }</Text>
<Flex columnGap={ 5 }>
{ fieldsLength > 1 && (
<IconButton
aria-label="delete"
variant="outline"
w="30px"
h="30px"
onClick={ handleRemoveButtonClick }
icon={ <Icon as={ minusIcon } w="20px" h="20px"/> }
/>
) }
{ fieldsLength < LIMIT && (
<IconButton
aria-label="add"
variant="outline"
w="30px"
h="30px"
onClick={ handleAddButtonClick }
icon={ <Icon as={ plusIcon } w="20px" h="20px"/> }
/>
) }
</Flex>
</Flex>
</GridItem>
<GridItem/>
<GridItem>
<Controller
name={ `libraries.${ index }.name` }
control={ control }
render={ renderNameControl }
rules={{ required: true }}
/>
</GridItem>
{ index === 0 ? (
<GridItem fontSize="sm">
A library name called in the .sol file. Multiple libraries (up to 10) may be added for each contract.
</GridItem>
) : <GridItem/> }
<GridItem>
<Controller
name={ `libraries.${ index }.address` }
control={ control }
render={ renderAddressControl }
rules={{ required: true, pattern: ADDRESS_REGEXP }}
/>
</GridItem>
{ index === 0 ? (
<GridItem fontSize="sm">
The 0x library address. This can be found in the generated json file or Truffle output (if using truffle).
</GridItem>
) : <GridItem/> }
</>
);
};
export default React.memo(ContractVerificationFieldLibraryItem);
...@@ -4,11 +4,12 @@ import type { Control } from 'react-hook-form'; ...@@ -4,11 +4,12 @@ import type { Control } from 'react-hook-form';
import type { FormFields } from '../types'; import type { FormFields } from '../types';
import ContractVerificationMethod from '../ContractVerificationMethod'; import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationEvmVersion from '../fields/ContractVerificationEvmVersion';
import ContractVerificationFieldCode from '../fields/ContractVerificationFieldCode'; import ContractVerificationFieldCode from '../fields/ContractVerificationFieldCode';
import ContractVerificationFieldCompiler from '../fields/ContractVerificationFieldCompiler'; import ContractVerificationFieldCompiler from '../fields/ContractVerificationFieldCompiler';
import ContractVerificationFieldIsConstArgs from '../fields/ContractVerificationFieldIsConstArgs'; import ContractVerificationFieldConstArgs from '../fields/ContractVerificationFieldConstArgs';
import ContractVerificationFieldEvmVersion from '../fields/ContractVerificationFieldEvmVersion';
import ContractVerificationFieldIsYul from '../fields/ContractVerificationFieldIsYul'; import ContractVerificationFieldIsYul from '../fields/ContractVerificationFieldIsYul';
import ContractVerificationFieldLibraries from '../fields/ContractVerificationFieldLibraries';
import ContractVerificationFieldName from '../fields/ContractVerificationFieldName'; import ContractVerificationFieldName from '../fields/ContractVerificationFieldName';
import ContractVerificationFieldOptimization from '../fields/ContractVerificationFieldOptimization'; import ContractVerificationFieldOptimization from '../fields/ContractVerificationFieldOptimization';
...@@ -22,10 +23,11 @@ const ContractVerificationFlattenSourceCode = ({ control }: Props) => { ...@@ -22,10 +23,11 @@ const ContractVerificationFlattenSourceCode = ({ control }: Props) => {
<ContractVerificationFieldIsYul control={ control }/> <ContractVerificationFieldIsYul control={ control }/>
<ContractVerificationFieldName control={ control }/> <ContractVerificationFieldName control={ control }/>
<ContractVerificationFieldCompiler control={ control }/> <ContractVerificationFieldCompiler control={ control }/>
<ContractVerificationEvmVersion control={ control }/> <ContractVerificationFieldEvmVersion control={ control }/>
<ContractVerificationFieldOptimization control={ control }/> <ContractVerificationFieldOptimization control={ control }/>
<ContractVerificationFieldCode control={ control }/> <ContractVerificationFieldCode control={ control }/>
<ContractVerificationFieldIsConstArgs control={ control }/> <ContractVerificationFieldConstArgs control={ control }/>
<ContractVerificationFieldLibraries control={ control }/>
</ContractVerificationMethod> </ContractVerificationMethod>
); );
}; };
......
export type VerificationMethod = 'flatten_source_code' | 'standard_input' | 'sourcify' | 'multi_part_file' | 'vyper_contract' export type VerificationMethod = 'flatten_source_code' | 'standard_input' | 'sourcify' | 'multi_part_file' | 'vyper_contract'
export interface ContractLibrary {
name: string;
address: string;
}
export interface FormFieldsFlattenSourceCode { export interface FormFieldsFlattenSourceCode {
method: 'flatten_source_code'; method: 'flatten_source_code';
is_yul: boolean; is_yul: boolean;
...@@ -10,6 +14,7 @@ export interface FormFieldsFlattenSourceCode { ...@@ -10,6 +14,7 @@ export interface FormFieldsFlattenSourceCode {
optimization_runs: string; optimization_runs: string;
code: string; code: string;
constructor_args: boolean; constructor_args: boolean;
libraries: Array<ContractLibrary>;
} }
export interface FormFieldsStandardInput { export interface FormFieldsStandardInput {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment