Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
ca46b77f
Commit
ca46b77f
authored
Feb 14, 2023
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
method field changes
parent
27974d19
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
149 additions
and
118 deletions
+149
-118
ContractVerificationForm.tsx
ui/contractVerification/ContractVerificationForm.tsx
+8
-5
ContractVerificationFieldMethod.tsx
...ctVerification/fields/ContractVerificationFieldMethod.tsx
+69
-76
types.ts
ui/contractVerification/types.ts
+13
-6
utils.ts
ui/contractVerification/utils.ts
+59
-31
No files found.
ui/contractVerification/ContractVerificationForm.tsx
View file @
ca46b77f
...
...
@@ -21,7 +21,7 @@ import ContractVerificationSourcify from './methods/ContractVerificationSourcify
import
ContractVerificationStandardInput
from
'
./methods/ContractVerificationStandardInput
'
;
import
ContractVerificationVyperContract
from
'
./methods/ContractVerificationVyperContract
'
;
import
ContractVerificationVyperMultiPartFile
from
'
./methods/ContractVerificationVyperMultiPartFile
'
;
import
{
prepareRequestBody
,
formatSocketErrors
}
from
'
./utils
'
;
import
{
prepareRequestBody
,
formatSocketErrors
,
METHOD_LABELS
}
from
'
./utils
'
;
const
METHOD_COMPONENTS
=
{
'
flattened-code
'
:
<
ContractVerificationFlattenSourceCode
/>
,
...
...
@@ -42,7 +42,10 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
const
formApi
=
useForm
<
FormFields
>
({
mode
:
'
onBlur
'
,
defaultValues
:
{
method
:
methodFromQuery
,
method
:
methodFromQuery
?
{
value
:
methodFromQuery
,
label
:
METHOD_LABELS
[
methodFromQuery
],
}
:
undefined
,
},
});
const
{
control
,
handleSubmit
,
watch
,
formState
,
setError
}
=
formApi
;
...
...
@@ -57,7 +60,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
try
{
await
apiFetch
(
'
contract_verification_via
'
,
{
pathParams
:
{
method
:
data
.
method
,
id
:
hash
},
pathParams
:
{
method
:
data
.
method
.
value
,
id
:
hash
},
fetchParams
:
{
method
:
'
POST
'
,
body
,
...
...
@@ -125,7 +128,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
});
const
method
=
watch
(
'
method
'
);
const
content
=
METHOD_COMPONENTS
[
method
]
||
null
;
const
content
=
METHOD_COMPONENTS
[
method
?.
value
]
||
null
;
return
(
<
FormProvider
{
...
formApi
}
>
...
...
@@ -135,8 +138,8 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
>
<
ContractVerificationFieldMethod
control=
{
control
}
isDisabled=
{
Boolean
(
method
)
}
methods=
{
config
.
verification_options
}
isDisabled=
{
formState
.
isSubmitting
}
/>
{
content
}
{
Boolean
(
method
)
&&
(
...
...
ui/contractVerification/fields/ContractVerificationFieldMethod.tsx
View file @
ca46b77f
import
{
RadioGroup
,
Radio
,
Stack
,
Text
,
Link
,
Icon
,
chakra
,
...
...
@@ -14,16 +10,23 @@ import {
PopoverBody
,
useColorModeValue
,
DarkMode
,
useBoolean
,
ListItem
,
OrderedList
,
Grid
,
Box
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
ControllerRenderProps
,
Control
}
from
'
react-hook-form
'
;
import
{
Controller
}
from
'
react-hook-form
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
SmartContractVerification
Method
,
SmartContractVerification
Config
}
from
'
types/api/contract
'
;
import
type
{
SmartContractVerificationConfig
}
from
'
types/api/contract
'
;
import
infoIcon
from
'
icons/info.svg
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
FancySelect
from
'
ui/shared/FancySelect/FancySelect
'
;
import
{
METHOD_LABELS
}
from
'
../utils
'
;
interface
Props
{
control
:
Control
<
FormFields
>
;
...
...
@@ -32,91 +35,81 @@ interface Props {
}
const
ContractVerificationFieldMethod
=
({
control
,
isDisabled
,
methods
}:
Props
)
=>
{
const
[
isPopoverOpen
,
setIsPopoverOpen
]
=
useBoolean
();
const
tooltipBg
=
useColorModeValue
(
'
gray.700
'
,
'
gray.900
'
);
const
isMobile
=
useIsMobile
();
const
options
=
React
.
useMemo
(()
=>
methods
.
map
((
method
)
=>
({
value
:
method
,
label
:
METHOD_LABELS
[
method
],
})),
[
methods
]);
const
renderItem
=
React
.
useCallback
((
method
:
SmartContractVerificationMethod
)
=>
{
switch
(
method
)
{
case
'
flattened-code
'
:
return
'
Via flattened source code
'
;
case
'
standard-input
'
:
const
renderControl
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
FormFields
,
'
method
'
>
})
=>
{
return
(
<>
<
span
>
Via standard
</
span
>
<
Link
href=
{
isDisabled
?
undefined
:
'
https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description
'
}
target=
"_blank"
cursor=
{
isDisabled
?
'
not-allowed
'
:
'
pointer
'
}
>
Input JSON
</
Link
>
</>
<
FancySelect
{
...
field
}
options=
{
options
}
size=
{
isMobile
?
'
md
'
:
'
lg
'
}
placeholder=
"Verification method (compiler type)"
isDisabled=
{
isDisabled
}
isRequired
isAsync=
{
false
}
/>
);
case
'
sourcify
'
:
},
[
isDisabled
,
isMobile
,
options
]);
return
(
<>
<
span
>
Via sourcify: sources and metadata JSON file
</
span
>
<
Popover
trigger=
"hover"
isLazy
isOpen=
{
isDisabled
?
false
:
isPopoverOpen
}
onOpen=
{
setIsPopoverOpen
.
on
}
onClose=
{
setIsPopoverOpen
.
off
}
>
<
section
>
<
Grid
columnGap=
"30px"
rowGap=
{
{
base
:
2
,
lg
:
4
}
}
templateColumns=
{
{
base
:
'
1fr
'
,
lg
:
'
minmax(auto, 680px) minmax(0, 340px)
'
}
}
>
<
div
>
<
Box
mb=
{
5
}
>
<
chakra
.
span
fontWeight=
{
500
}
fontSize=
"lg"
fontFamily=
"heading"
>
Currently, Blockscout supports
{
methods
.
length
}
contract verification methods
</
chakra
.
span
>
<
Popover
trigger=
"hover"
isLazy
placement=
{
isMobile
?
'
bottom-end
'
:
'
right-start
'
}
>
<
PopoverTrigger
>
<
chakra
.
span
cursor=
{
isDisabled
?
'
not-allowed
'
:
'
pointer
'
}
display=
"inline-block"
verticalAlign=
"middle"
h=
"24px"
ml=
{
1
}
>
<
chakra
.
span
display=
"inline-block"
ml=
{
1
}
cursor=
"pointer"
verticalAlign=
"middle"
h=
"22px"
>
<
Icon
as=
{
infoIcon
}
boxSize=
{
5
}
color=
"link"
_hover=
{
{
color
:
'
link_hovered
'
}
}
/>
</
chakra
.
span
>
</
PopoverTrigger
>
<
Portal
>
<
PopoverContent
bgColor=
{
tooltipBg
}
>
<
PopoverContent
bgColor=
{
tooltipBg
}
w=
{
{
base
:
'
300px
'
,
lg
:
'
380px
'
}
}
>
<
PopoverArrow
bgColor=
{
tooltipBg
}
/>
<
PopoverBody
color=
"white"
>
<
DarkMode
>
<
div
>
<
span
>
Verification through
</
span
>
<
Link
href=
"https://sourcify.dev/"
target=
"_blank"
>
Sourcify
</
Link
>
</
div
>
<
div
>
<
span
>
a) if smart-contract already verified on Sourcify, it will automatically fetch the data from the
</
span
>
<
Link
href=
"https://repo.sourcify.dev/"
target=
"_blank"
>
repo
</
Link
>
</
div
>
<
div
>
b) otherwise you will be asked to upload source files and JSON metadata file(s).
</
div
>
<
span
>
Currently, Blockscout supports 6 methods:
</
span
>
<
OrderedList
>
<
ListItem
>
Verification through flattened source code.
</
ListItem
>
<
ListItem
>
<
span
>
Verification using
</
span
>
<
Link
href=
"https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description"
target=
"_blank"
>
Standard input JSON
</
Link
>
<
span
>
file.
</
span
>
</
ListItem
>
<
ListItem
>
Verification through
<
Link
href=
"https://sourcify.dev/"
target=
"_blank"
>
Sourcify
</
Link
>
.
</
ListItem
>
<
ListItem
>
Verification of multi-part Solidity files.
</
ListItem
>
<
ListItem
>
Verification of Vyper contract.
</
ListItem
>
<
ListItem
>
Verification of multi-part Vyper files.
</
ListItem
>
</
OrderedList
>
</
DarkMode
>
</
PopoverBody
>
</
PopoverContent
>
</
Portal
>
</
Popover
>
</>
);
case
'
multi-part
'
:
return
'
Via multi-part files
'
;
case
'
vyper-code
'
:
return
'
Vyper contract
'
;
case
'
vyper-multi-part
'
:
return
'
Via multi-part Vyper files
'
;
default
:
break
;
}
},
[
isDisabled
,
isPopoverOpen
,
setIsPopoverOpen
.
off
,
setIsPopoverOpen
.
on
,
tooltipBg
]);
const
renderRadioGroup
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
FormFields
,
'
method
'
>
})
=>
{
return
(
<
RadioGroup
defaultValue=
"add"
colorScheme=
"blue"
isDisabled=
{
isDisabled
}
isFocusable=
{
!
isDisabled
}
{
...
field
}
>
<
Stack
spacing=
{
4
}
>
{
methods
.
map
((
method
)
=>
{
return
<
Radio
key=
{
method
}
value=
{
method
}
size=
"lg"
>
{
renderItem
(
method
)
}
</
Radio
>;
})
}
</
Stack
>
</
RadioGroup
>
);
},
[
isDisabled
,
methods
,
renderItem
]);
return
(
<
section
>
<
Text
variant=
"secondary"
fontSize=
"sm"
mb=
{
5
}
>
Smart-contract verification method
</
Text
>
</
Box
>
<
Controller
name=
"method"
control=
{
control
}
render=
{
renderRadioGroup
}
render=
{
renderControl
}
rules=
{
{
required
:
true
}
}
/>
</
div
>
</
Grid
>
</
section
>
);
};
...
...
ui/contractVerification/types.ts
View file @
ca46b77f
import
type
{
SmartContractVerificationMethod
}
from
'
types/api/contract
'
;
import
type
{
Option
}
from
'
ui/shared/FancySelect/types
'
;
export
interface
ContractLibrary
{
name
:
string
;
address
:
string
;
}
interface
MethodOption
{
label
:
string
;
value
:
SmartContractVerificationMethod
;
}
export
interface
FormFieldsFlattenSourceCode
{
method
:
'
flattened-code
'
;
method
:
MethodOption
;
is_yul
:
boolean
;
name
:
string
;
compiler
:
Option
;
...
...
@@ -19,7 +26,7 @@ export interface FormFieldsFlattenSourceCode {
}
export
interface
FormFieldsStandardInput
{
method
:
'
standard-input
'
;
method
:
MethodOption
;
name
:
string
;
compiler
:
Option
;
sources
:
Array
<
File
>
;
...
...
@@ -28,12 +35,12 @@ export interface FormFieldsStandardInput {
}
export
interface
FormFieldsSourcify
{
method
:
'
sourcify
'
;
method
:
MethodOption
;
sources
:
Array
<
File
>
;
}
export
interface
FormFieldsMultiPartFile
{
method
:
'
multi-part
'
;
method
:
MethodOption
;
compiler
:
Option
;
evm_version
:
Option
;
is_optimization_enabled
:
boolean
;
...
...
@@ -43,7 +50,7 @@ export interface FormFieldsMultiPartFile {
}
export
interface
FormFieldsVyperContract
{
method
:
'
vyper-code
'
;
method
:
MethodOption
;
name
:
string
;
compiler
:
Option
;
code
:
string
;
...
...
@@ -51,7 +58,7 @@ export interface FormFieldsVyperContract {
}
export
interface
FormFieldsVyperMultiPartFile
{
method
:
'
vyper-multi-part
'
;
method
:
MethodOption
;
compiler
:
Option
;
evm_version
:
Option
;
sources
:
Array
<
File
>
;
...
...
ui/contractVerification/utils.ts
View file @
ca46b77f
import
type
{
FieldPath
,
ErrorOption
}
from
'
react-hook-form
'
;
import
type
{
ContractLibrary
,
FormFields
}
from
'
./types
'
;
import
type
{
ContractLibrary
,
FormFields
,
FormFieldsFlattenSourceCode
,
FormFieldsMultiPartFile
,
FormFieldsSourcify
,
FormFieldsStandardInput
,
FormFieldsVyperContract
,
FormFieldsVyperMultiPartFile
,
}
from
'
./types
'
;
import
type
{
SmartContractVerificationMethod
,
SmartContractVerificationError
}
from
'
types/api/contract
'
;
import
type
{
Params
as
FetchParams
}
from
'
lib/hooks/useFetch
'
;
...
...
@@ -14,6 +23,15 @@ export const SUPPORTED_VERIFICATION_METHODS: Array<SmartContractVerificationMeth
'
vyper-multi-part
'
,
];
export
const
METHOD_LABELS
:
Record
<
SmartContractVerificationMethod
,
string
>
=
{
'
flattened-code
'
:
'
Solidity (Flattened source code)
'
,
'
standard-input
'
:
'
Solidity (Standart JSON input)
'
,
sourcify
:
'
Solidity (Sourcify)
'
,
'
multi-part
'
:
'
Solidity (Multi-part files)
'
,
'
vyper-code
'
:
'
Vyper (Сontract)
'
,
'
vyper-multi-part
'
:
'
Vyper (Multi-part files)
'
,
};
export
function
isValidVerificationMethod
(
method
?:
string
):
method
is
SmartContractVerificationMethod
{
return
method
&&
SUPPORTED_VERIFICATION_METHODS
.
includes
(
method
as
SmartContractVerificationMethod
)
?
true
:
false
;
}
...
...
@@ -34,68 +52,78 @@ export function sortVerificationMethods(methodA: SmartContractVerificationMethod
}
export
function
prepareRequestBody
(
data
:
FormFields
):
FetchParams
[
'
body
'
]
{
switch
(
data
.
method
)
{
switch
(
data
.
method
.
value
)
{
case
'
flattened-code
'
:
{
const
_data
=
data
as
FormFieldsFlattenSourceCode
;
return
{
compiler_version
:
data
.
compiler
?.
value
,
source_code
:
data
.
code
,
is_optimization_enabled
:
data
.
is_optimization_enabled
,
is_yul_contract
:
data
.
is_yul
,
optimization_runs
:
data
.
optimization_runs
,
contract_name
:
data
.
name
,
libraries
:
reduceLibrariesArray
(
data
.
libraries
),
evm_version
:
data
.
evm_version
?.
value
,
autodetect_constructor_args
:
data
.
autodetect_constructor_args
,
constructor_args
:
data
.
constructor_args
,
compiler_version
:
_
data
.
compiler
?.
value
,
source_code
:
_
data
.
code
,
is_optimization_enabled
:
_
data
.
is_optimization_enabled
,
is_yul_contract
:
_
data
.
is_yul
,
optimization_runs
:
_
data
.
optimization_runs
,
contract_name
:
_
data
.
name
,
libraries
:
reduceLibrariesArray
(
_
data
.
libraries
),
evm_version
:
_
data
.
evm_version
?.
value
,
autodetect_constructor_args
:
_
data
.
autodetect_constructor_args
,
constructor_args
:
_
data
.
constructor_args
,
};
}
case
'
standard-input
'
:
{
const
_data
=
data
as
FormFieldsStandardInput
;
const
body
=
new
FormData
();
body
.
set
(
'
compiler_version
'
,
data
.
compiler
?.
value
);
body
.
set
(
'
contract_name
'
,
data
.
name
);
body
.
set
(
'
autodetect_constructor_args
'
,
String
(
Boolean
(
data
.
autodetect_constructor_args
)));
body
.
set
(
'
constructor_args
'
,
data
.
constructor_args
);
addFilesToFormData
(
body
,
data
.
sources
);
body
.
set
(
'
compiler_version
'
,
_
data
.
compiler
?.
value
);
body
.
set
(
'
contract_name
'
,
_
data
.
name
);
body
.
set
(
'
autodetect_constructor_args
'
,
String
(
Boolean
(
_
data
.
autodetect_constructor_args
)));
body
.
set
(
'
constructor_args
'
,
_
data
.
constructor_args
);
addFilesToFormData
(
body
,
_
data
.
sources
);
return
body
;
}
case
'
sourcify
'
:
{
const
_data
=
data
as
FormFieldsSourcify
;
const
body
=
new
FormData
();
addFilesToFormData
(
body
,
data
.
sources
);
addFilesToFormData
(
body
,
_
data
.
sources
);
return
body
;
}
case
'
multi-part
'
:
{
const
_data
=
data
as
FormFieldsMultiPartFile
;
const
body
=
new
FormData
();
body
.
set
(
'
compiler_version
'
,
data
.
compiler
?.
value
);
body
.
set
(
'
evm_version
'
,
data
.
evm_version
?.
value
);
body
.
set
(
'
is_optimization_enabled
'
,
String
(
Boolean
(
data
.
is_optimization_enabled
)));
data
.
is_optimization_enabled
&&
body
.
set
(
'
optimization_runs
'
,
data
.
optimization_runs
);
body
.
set
(
'
compiler_version
'
,
_
data
.
compiler
?.
value
);
body
.
set
(
'
evm_version
'
,
_
data
.
evm_version
?.
value
);
body
.
set
(
'
is_optimization_enabled
'
,
String
(
Boolean
(
_
data
.
is_optimization_enabled
)));
_data
.
is_optimization_enabled
&&
body
.
set
(
'
optimization_runs
'
,
_
data
.
optimization_runs
);
const
libraries
=
reduceLibrariesArray
(
data
.
libraries
);
const
libraries
=
reduceLibrariesArray
(
_
data
.
libraries
);
libraries
&&
body
.
set
(
'
libraries
'
,
JSON
.
stringify
(
libraries
));
addFilesToFormData
(
body
,
data
.
sources
);
addFilesToFormData
(
body
,
_
data
.
sources
);
return
body
;
}
case
'
vyper-code
'
:
{
const
_data
=
data
as
FormFieldsVyperContract
;
return
{
compiler_version
:
data
.
compiler
?.
value
,
source_code
:
data
.
code
,
contract_name
:
data
.
name
,
constructor_args
:
data
.
constructor_args
,
compiler_version
:
_
data
.
compiler
?.
value
,
source_code
:
_
data
.
code
,
contract_name
:
_
data
.
name
,
constructor_args
:
_
data
.
constructor_args
,
};
}
case
'
vyper-multi-part
'
:
{
const
_data
=
data
as
FormFieldsVyperMultiPartFile
;
const
body
=
new
FormData
();
body
.
set
(
'
compiler_version
'
,
data
.
compiler
?.
value
);
body
.
set
(
'
evm_version
'
,
data
.
evm_version
?.
value
);
addFilesToFormData
(
body
,
data
.
sources
);
body
.
set
(
'
compiler_version
'
,
_
data
.
compiler
?.
value
);
body
.
set
(
'
evm_version
'
,
_
data
.
evm_version
?.
value
);
addFilesToFormData
(
body
,
_
data
.
sources
);
return
body
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment