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
532f7e7a
Commit
532f7e7a
authored
Mar 06, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
contract verification: flattened code method
parent
cdb1793c
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
318 additions
and
284 deletions
+318
-284
eslint.config.mjs
eslint.config.mjs
+1
-0
contract-verification.tsx
pages/address/[hash]/contract-verification.tsx
+2
-2
contract-verification.tsx
pages/contract-verification.tsx
+2
-2
index.ts
toolkit/theme/recipes/index.ts
+2
-0
input.recipe.ts
toolkit/theme/recipes/input.recipe.ts
+3
-0
list.recipe.ts
toolkit/theme/recipes/list.recipe.ts
+67
-0
ContractVerificationForm.tsx
ui/contractVerification/ContractVerificationForm.tsx
+32
-43
ContractVerificationFieldAddress.tsx
...tVerification/fields/ContractVerificationFieldAddress.tsx
+4
-5
ContractVerificationFieldCode.tsx
...ractVerification/fields/ContractVerificationFieldCode.tsx
+1
-2
ContractVerificationFieldCompiler.tsx
...Verification/fields/ContractVerificationFieldCompiler.tsx
+31
-21
ContractVerificationFieldConstructorArgs.tsx
...ation/fields/ContractVerificationFieldConstructorArgs.tsx
+2
-3
ContractVerificationFieldEvmVersion.tsx
...rification/fields/ContractVerificationFieldEvmVersion.tsx
+11
-8
ContractVerificationFieldLibraries.tsx
...erification/fields/ContractVerificationFieldLibraries.tsx
+4
-3
ContractVerificationFieldLibraryItem.tsx
...ification/fields/ContractVerificationFieldLibraryItem.tsx
+14
-13
ContractVerificationFieldLicenseType.tsx
...ification/fields/ContractVerificationFieldLicenseType.tsx
+7
-4
ContractVerificationFieldMethod.tsx
...ctVerification/fields/ContractVerificationFieldMethod.tsx
+41
-57
ContractVerificationFieldName.tsx
...ractVerification/fields/ContractVerificationFieldName.tsx
+1
-2
ContractVerificationFieldOptimization.tsx
...fication/fields/ContractVerificationFieldOptimization.tsx
+5
-3
types.ts
ui/contractVerification/types.ts
+15
-20
utils.ts
ui/contractVerification/utils.ts
+58
-91
ContractVerificationForAddress.tsx
ui/pages/ContractVerificationForAddress.tsx
+2
-0
VerifiedAddresses.tsx
ui/pages/VerifiedAddresses.tsx
+2
-2
FormFieldText.tsx
ui/shared/forms/fields/FormFieldText.tsx
+11
-3
No files found.
eslint.config.mjs
View file @
532f7e7a
...
@@ -29,6 +29,7 @@ const RESTRICTED_MODULES = {
...
@@ -29,6 +29,7 @@ const RESTRICTED_MODULES = {
{
name
:
'
ui/shared/Tabs/RoutedTabs
'
,
message
:
'
Please use RoutedTabs component from toolkit/components/RoutedTabs instead
'
},
{
name
:
'
ui/shared/Tabs/RoutedTabs
'
,
message
:
'
Please use RoutedTabs component from toolkit/components/RoutedTabs instead
'
},
{
name
:
'
ui/shared/chakra/Tag
'
,
message
:
'
Please use Tag component from toolkit/chakra instead
'
},
{
name
:
'
ui/shared/chakra/Tag
'
,
message
:
'
Please use Tag component from toolkit/chakra instead
'
},
{
name
:
'
ui/shared/select/Select
'
,
message
:
'
Please use Select component from toolkit/chakra instead
'
},
{
name
:
'
ui/shared/select/Select
'
,
message
:
'
Please use Select component from toolkit/chakra instead
'
},
{
name
:
'
ui/shared/forms/fields/FormFieldFancySelect
'
,
message
:
'
Please use FormFieldSelect component
'
},
{
{
name
:
'
@chakra-ui/react
'
,
name
:
'
@chakra-ui/react
'
,
importNames
:
[
importNames
:
[
...
...
pages/address/[hash]/contract-verification.tsx
View file @
532f7e7a
...
@@ -4,12 +4,12 @@ import React from 'react';
...
@@ -4,12 +4,12 @@ import React from 'react';
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import ContractVerificationForAddress from 'ui/pages/ContractVerificationForAddress';
import
ContractVerificationForAddress
from
'
ui/pages/ContractVerificationForAddress
'
;
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/address/[hash]/contract-verification"
query=
{
props
.
query
}
>
<
PageNextJs
pathname=
"/address/[hash]/contract-verification"
query=
{
props
.
query
}
>
{
/* <ContractVerificationForAddress/> */
}
<
ContractVerificationForAddress
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
pages/contract-verification.tsx
View file @
532f7e7a
...
@@ -4,12 +4,12 @@ import React from 'react';
...
@@ -4,12 +4,12 @@ import React from 'react';
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
import ContractVerification from 'ui/pages/ContractVerification';
import
ContractVerification
from
'
ui/pages/ContractVerification
'
;
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
return
(
return
(
<
PageNextJs
pathname=
"/contract-verification"
query=
{
props
.
query
}
>
<
PageNextJs
pathname=
"/contract-verification"
query=
{
props
.
query
}
>
{
/* <ContractVerification/> */
}
<
ContractVerification
/>
</
PageNextJs
>
</
PageNextJs
>
);
);
};
};
...
...
toolkit/theme/recipes/index.ts
View file @
532f7e7a
...
@@ -10,6 +10,7 @@ import { recipe as drawer } from './drawer.recipe';
...
@@ -10,6 +10,7 @@ import { recipe as drawer } from './drawer.recipe';
import
{
recipe
as
field
}
from
'
./field.recipe
'
;
import
{
recipe
as
field
}
from
'
./field.recipe
'
;
import
{
recipe
as
input
}
from
'
./input.recipe
'
;
import
{
recipe
as
input
}
from
'
./input.recipe
'
;
import
{
recipe
as
link
}
from
'
./link.recipe
'
;
import
{
recipe
as
link
}
from
'
./link.recipe
'
;
import
{
recipe
as
list
}
from
'
./list.recipe
'
;
import
{
recipe
as
menu
}
from
'
./menu.recipe
'
;
import
{
recipe
as
menu
}
from
'
./menu.recipe
'
;
import
{
recipe
as
nativeSelect
}
from
'
./native-select.recipe
'
;
import
{
recipe
as
nativeSelect
}
from
'
./native-select.recipe
'
;
import
{
recipe
as
pinInput
}
from
'
./pin-input.recipe
'
;
import
{
recipe
as
pinInput
}
from
'
./pin-input.recipe
'
;
...
@@ -49,6 +50,7 @@ export const slotRecipes = {
...
@@ -49,6 +50,7 @@ export const slotRecipes = {
dialog
,
dialog
,
drawer
,
drawer
,
field
,
field
,
list
,
menu
,
menu
,
nativeSelect
,
nativeSelect
,
pinInput
,
pinInput
,
...
...
toolkit/theme/recipes/input.recipe.ts
View file @
532f7e7a
...
@@ -64,6 +64,9 @@ export const recipe = defineRecipe({
...
@@ -64,6 +64,9 @@ export const recipe = defineRecipe({
},
},
_placeholderShown
:
{
_placeholderShown
:
{
borderColor
:
'
input.border
'
,
borderColor
:
'
input.border
'
,
_invalid
:
{
borderColor
:
'
input.border.error
'
,
},
},
},
_hover
:
{
_hover
:
{
borderColor
:
'
input.border.hover
'
,
borderColor
:
'
input.border.hover
'
,
...
...
toolkit/theme/recipes/list.recipe.ts
0 → 100644
View file @
532f7e7a
import
{
defineSlotRecipe
}
from
'
@chakra-ui/react
'
;
export
const
recipe
=
defineSlotRecipe
({
slots
:
[
'
root
'
,
'
item
'
,
'
indicator
'
],
base
:
{
root
:
{
display
:
'
flex
'
,
flexDirection
:
'
column
'
,
gap
:
'
var(--list-gap)
'
,
'
& :where(ul, ol)
'
:
{
marginTop
:
'
var(--list-gap)
'
,
},
},
item
:
{
whiteSpace
:
'
normal
'
,
display
:
'
list-item
'
,
'
&::marker
'
:
{
color
:
'
inherit
'
,
},
},
indicator
:
{
marginEnd
:
'
2
'
,
minHeight
:
'
1lh
'
,
flexShrink
:
0
,
display
:
'
inline-block
'
,
verticalAlign
:
'
middle
'
,
},
},
variants
:
{
variant
:
{
marker
:
{
root
:
{
listStyle
:
'
revert
'
,
},
item
:
{
_marker
:
{
color
:
'
inherit
'
,
},
},
},
plain
:
{
item
:
{
alignItems
:
'
flex-start
'
,
display
:
'
inline-flex
'
,
},
},
},
align
:
{
center
:
{
item
:
{
alignItems
:
'
center
'
},
},
start
:
{
item
:
{
alignItems
:
'
flex-start
'
},
},
end
:
{
item
:
{
alignItems
:
'
flex-end
'
},
},
},
},
defaultVariants
:
{
variant
:
'
marker
'
,
},
});
ui/contractVerification/ContractVerificationForm.tsx
View file @
532f7e7a
import
{
Button
,
Grid
,
Text
,
chakra
,
useUpdateEffect
}
from
'
@chakra-ui/react
'
;
import
{
Grid
,
Text
,
chakra
,
useUpdateEffect
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
...
@@ -14,24 +14,25 @@ import useApiFetch from 'lib/api/useApiFetch';
...
@@ -14,24 +14,25 @@ import useApiFetch from 'lib/api/useApiFetch';
import
capitalizeFirstLetter
from
'
lib/capitalizeFirstLetter
'
;
import
capitalizeFirstLetter
from
'
lib/capitalizeFirstLetter
'
;
import
delay
from
'
lib/delay
'
;
import
delay
from
'
lib/delay
'
;
import
getErrorObjStatusCode
from
'
lib/errors/getErrorObjStatusCode
'
;
import
getErrorObjStatusCode
from
'
lib/errors/getErrorObjStatusCode
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketChannel
from
'
lib/socket/useSocketChannel
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
useSocketMessage
from
'
lib/socket/useSocketMessage
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
toaster
}
from
'
toolkit/chakra/toaster
'
;
import
ContractVerificationFieldAddress
from
'
./fields/ContractVerificationFieldAddress
'
;
import
ContractVerificationFieldAddress
from
'
./fields/ContractVerificationFieldAddress
'
;
import
ContractVerificationFieldLicenseType
from
'
./fields/ContractVerificationFieldLicenseType
'
;
import
ContractVerificationFieldLicenseType
from
'
./fields/ContractVerificationFieldLicenseType
'
;
import
ContractVerificationFieldMethod
from
'
./fields/ContractVerificationFieldMethod
'
;
import
ContractVerificationFieldMethod
from
'
./fields/ContractVerificationFieldMethod
'
;
import
ContractVerificationFlattenSourceCode
from
'
./methods/ContractVerificationFlattenSourceCode
'
;
import
ContractVerificationFlattenSourceCode
from
'
./methods/ContractVerificationFlattenSourceCode
'
;
import
ContractVerificationMultiPartFile
from
'
./methods/ContractVerificationMultiPartFile
'
;
//
import ContractVerificationMultiPartFile from './methods/ContractVerificationMultiPartFile';
import
ContractVerificationSolidityFoundry
from
'
./methods/ContractVerificationSolidityFoundry
'
;
//
import ContractVerificationSolidityFoundry from './methods/ContractVerificationSolidityFoundry';
import
ContractVerificationSolidityHardhat
from
'
./methods/ContractVerificationSolidityHardhat
'
;
//
import ContractVerificationSolidityHardhat from './methods/ContractVerificationSolidityHardhat';
import
ContractVerificationSourcify
from
'
./methods/ContractVerificationSourcify
'
;
//
import ContractVerificationSourcify from './methods/ContractVerificationSourcify';
import
ContractVerificationStandardInput
from
'
./methods/ContractVerificationStandardInput
'
;
//
import ContractVerificationStandardInput from './methods/ContractVerificationStandardInput';
import
ContractVerificationStylusGitHubRepo
from
'
./methods/ContractVerificationStylusGitHubRepo
'
;
//
import ContractVerificationStylusGitHubRepo from './methods/ContractVerificationStylusGitHubRepo';
import
ContractVerificationVyperContract
from
'
./methods/ContractVerificationVyperContract
'
;
//
import ContractVerificationVyperContract from './methods/ContractVerificationVyperContract';
import
ContractVerificationVyperMultiPartFile
from
'
./methods/ContractVerificationVyperMultiPartFile
'
;
//
import ContractVerificationVyperMultiPartFile from './methods/ContractVerificationVyperMultiPartFile';
import
ContractVerificationVyperStandardInput
from
'
./methods/ContractVerificationVyperStandardInput
'
;
//
import ContractVerificationVyperStandardInput from './methods/ContractVerificationVyperStandardInput';
import
{
prepareRequestBody
,
formatSocketErrors
,
getDefaultValues
,
METHOD_LABELS
}
from
'
./utils
'
;
import
{
prepareRequestBody
,
formatSocketErrors
,
getDefaultValues
,
METHOD_LABELS
}
from
'
./utils
'
;
interface
Props
{
interface
Props
{
...
@@ -43,14 +44,13 @@ interface Props {
...
@@ -43,14 +44,13 @@ interface Props {
const
ContractVerificationForm
=
({
method
:
methodFromQuery
,
config
,
hash
}:
Props
)
=>
{
const
ContractVerificationForm
=
({
method
:
methodFromQuery
,
config
,
hash
}:
Props
)
=>
{
const
formApi
=
useForm
<
FormFields
>
({
const
formApi
=
useForm
<
FormFields
>
({
mode
:
'
onBlur
'
,
mode
:
'
onBlur
'
,
defaultValues
:
getDefaultValues
(
methodFromQuery
,
config
,
hash
,
null
),
defaultValues
:
getDefaultValues
(
methodFromQuery
,
config
,
hash
,
[]
),
});
});
const
{
handleSubmit
,
watch
,
formState
,
setError
,
reset
,
getFieldState
,
getValues
,
clearErrors
}
=
formApi
;
const
{
handleSubmit
,
watch
,
formState
,
setError
,
reset
,
getFieldState
,
getValues
,
clearErrors
}
=
formApi
;
const
submitPromiseResolver
=
React
.
useRef
<
(
value
:
unknown
)
=>
void
>
();
const
submitPromiseResolver
=
React
.
useRef
<
(
value
:
unknown
)
=>
void
>
();
const
methodNameRef
=
React
.
useRef
<
string
>
();
const
methodNameRef
=
React
.
useRef
<
string
>
();
const
apiFetch
=
useApiFetch
();
const
apiFetch
=
useApiFetch
();
const
toast
=
useToast
();
const
onFormSubmit
:
SubmitHandler
<
FormFields
>
=
React
.
useCallback
(
async
(
data
)
=>
{
const
onFormSubmit
:
SubmitHandler
<
FormFields
>
=
React
.
useCallback
(
async
(
data
)
=>
{
const
body
=
prepareRequestBody
(
data
);
const
body
=
prepareRequestBody
(
data
);
...
@@ -76,7 +76,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -76,7 +76,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
try
{
try
{
await
apiFetch
(
'
contract_verification_via
'
,
{
await
apiFetch
(
'
contract_verification_via
'
,
{
pathParams
:
{
method
:
data
.
method
.
value
,
hash
:
data
.
address
.
toLowerCase
()
},
pathParams
:
{
method
:
data
.
method
[
0
]
,
hash
:
data
.
address
.
toLowerCase
()
},
fetchParams
:
{
fetchParams
:
{
method
:
'
POST
'
,
method
:
'
POST
'
,
body
,
body
,
...
@@ -116,13 +116,9 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -116,13 +116,9 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
return
;
return
;
}
}
toast
({
toaster
.
success
({
position
:
'
top-right
'
,
title
:
'
Success
'
,
title
:
'
Success
'
,
description
:
'
Contract is successfully verified.
'
,
description
:
'
Contract is successfully verified.
'
,
status
:
'
success
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
});
mixpanel
.
logEvent
(
mixpanel
.
logEvent
(
...
@@ -132,7 +128,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -132,7 +128,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
);
);
window
.
location
.
assign
(
route
({
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
address
,
tab
:
'
contract
'
}
}));
window
.
location
.
assign
(
route
({
pathname
:
'
/address/[hash]
'
,
query
:
{
hash
:
address
,
tab
:
'
contract
'
}
}));
},
[
setError
,
toast
,
address
,
getValues
]);
},
[
setError
,
address
,
getValues
]);
const
handleSocketError
=
React
.
useCallback
(()
=>
{
const
handleSocketError
=
React
.
useCallback
(()
=>
{
if
(
!
formState
.
isSubmitting
)
{
if
(
!
formState
.
isSubmitting
)
{
...
@@ -141,20 +137,14 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -141,20 +137,14 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
submitPromiseResolver
.
current
?.(
null
);
submitPromiseResolver
.
current
?.(
null
);
const
toastId
=
'
socket-error
'
;
toaster
.
error
({
!
toast
.
isActive
(
toastId
)
&&
toast
({
id
:
toastId
,
position
:
'
top-right
'
,
title
:
'
Error
'
,
title
:
'
Error
'
,
description
:
'
There was an error with socket connection. Try again later.
'
,
description
:
'
There was an error with socket connection. Try again later.
'
,
status
:
'
error
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
});
// callback should not change when form is submitted
// callback should not change when form is submitted
// otherwise it will resubscribe to channel, but we don't want that since in that case we might miss verification result message
// otherwise it will resubscribe to channel, but we don't want that since in that case we might miss verification result message
// eslint-disable-next-line react-hooks/exhaustive-deps
// eslint-disable-next-line react-hooks/exhaustive-deps
},
[
toast
]);
},
[
]);
const
channel
=
useSocketChannel
({
const
channel
=
useSocketChannel
({
topic
:
`addresses:
${
address
?.
toLowerCase
()
}
`,
topic
:
`addresses:
${
address
?.
toLowerCase
()
}
`,
...
@@ -171,21 +161,21 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -171,21 +161,21 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
const methods = React.useMemo(() => {
const methods = React.useMemo(() => {
return {
return {
'flattened-code': <ContractVerificationFlattenSourceCode config={ config }/>,
'flattened-code': <ContractVerificationFlattenSourceCode config={ config }/>,
'standard-input': <ContractVerificationStandardInput config={ config }/>,
//
'standard-input': <ContractVerificationStandardInput config={ config }/>,
sourcify: <ContractVerificationSourcify/>,
//
sourcify: <ContractVerificationSourcify/>,
'multi-part': <ContractVerificationMultiPartFile/>,
//
'multi-part': <ContractVerificationMultiPartFile/>,
'vyper-code': <ContractVerificationVyperContract config={ config }/>,
//
'vyper-code': <ContractVerificationVyperContract config={ config }/>,
'vyper-multi-part': <ContractVerificationVyperMultiPartFile/>,
//
'vyper-multi-part': <ContractVerificationVyperMultiPartFile/>,
'vyper-standard-input': <ContractVerificationVyperStandardInput/>,
//
'vyper-standard-input': <ContractVerificationVyperStandardInput/>,
'solidity-hardhat': <ContractVerificationSolidityHardhat config={ config }/>,
//
'solidity-hardhat': <ContractVerificationSolidityHardhat config={ config }/>,
'solidity-foundry': <ContractVerificationSolidityFoundry/>,
//
'solidity-foundry': <ContractVerificationSolidityFoundry/>,
'stylus-github-repository': <ContractVerificationStylusGitHubRepo/>,
//
'stylus-github-repository': <ContractVerificationStylusGitHubRepo/>,
};
};
}, [ config ]);
}, [ config ]);
const method = watch('method');
const method = watch('method');
const methodValue = method?.[0];
const licenseType = watch('license_type');
const licenseType = watch('license_type');
const content = methods[method?.value] || null;
const content = methods[methodValue] || null;
const methodValue = method?.value;
useUpdateEffect(() => {
useUpdateEffect(() => {
if (methodValue) {
if (methodValue) {
...
@@ -212,13 +202,12 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
...
@@ -212,13 +202,12 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
</Grid>
</Grid>
{ content }
{ content }
{ formState.errors.root?.message && <Text color="error"mt={ 4 } fontSize="sm" whiteSpace="pre-wrap">{ formState.errors.root.message }</Text> }
{ formState.errors.root?.message && <Text color="error"mt={ 4 } fontSize="sm" whiteSpace="pre-wrap">{ formState.errors.root.message }</Text> }
{ Boolean(method) && method
.value !== 'solidity-hardhat' && method.v
alue !== 'solidity-foundry' && (
{ Boolean(method) && method
Value !== 'solidity-hardhat' && methodV
alue !== 'solidity-foundry' && (
<Button
<Button
variant="solid"
size="md"
size="lg"
type="submit"
type="submit"
mt={ 12 }
mt={ 12 }
isL
oading={ formState.isSubmitting }
l
oading={ formState.isSubmitting }
loadingText="Verify & publish"
loadingText="Verify & publish"
>
>
Verify & publish
Verify & publish
...
...
ui/contractVerification/fields/ContractVerificationFieldAddress.tsx
View file @
532f7e7a
...
@@ -8,10 +8,10 @@ import FormFieldAddress from 'ui/shared/forms/fields/FormFieldAddress';
...
@@ -8,10 +8,10 @@ import FormFieldAddress from 'ui/shared/forms/fields/FormFieldAddress';
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
interface
Props
{
interface
Props
{
isR
eadOnly
?:
boolean
;
r
eadOnly
?:
boolean
;
}
}
const
ContractVerificationFieldAddress
=
({
isR
eadOnly
}:
Props
)
=>
{
const
ContractVerificationFieldAddress
=
({
r
eadOnly
}:
Props
)
=>
{
return
(
return
(
<>
<>
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
...
@@ -22,10 +22,9 @@ const ContractVerificationFieldAddress = ({ isReadOnly }: Props) => {
...
@@ -22,10 +22,9 @@ const ContractVerificationFieldAddress = ({ isReadOnly }: Props) => {
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldAddress
<
FormFields
>
<
FormFieldAddress
<
FormFields
>
name="address"
name="address"
isR
equired
r
equired
placeholder="Smart contract / Address (0x...)"
placeholder="Smart contract / Address (0x...)"
isReadOnly=
{
isReadOnly
}
readOnly=
{
readOnly
}
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
/
>
/
>
</
ContractVerificationFormRow
>
</
ContractVerificationFormRow
>
</>
</>
...
...
ui/contractVerification/fields/ContractVerificationFieldCode.tsx
View file @
532f7e7a
...
@@ -15,9 +15,8 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
...
@@ -15,9 +15,8 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldText
<
FormFields
>
<
FormFieldText
<
FormFields
>
name="code"
name="code"
isR
equired
r
equired
placeholder="Contract code"
placeholder="Contract code"
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
asComponent="Textarea"
asComponent="Textarea"
/
>
/
>
{
isVyper
?
null
:
(
{
isVyper
?
null
:
(
...
...
ui/contractVerification/fields/ContractVerificationFieldCompiler.tsx
View file @
532f7e7a
import
{
chakra
,
C
heckbox
,
Code
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
C
ode
,
createListCollection
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
import
{
useFormContext
}
from
'
react-hook-form
'
;
...
@@ -7,8 +7,8 @@ import type { FormFields } from '../types';
...
@@ -7,8 +7,8 @@ import type { FormFields } from '../types';
import
type
{
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
type
{
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
FormFieldFancySelect
from
'
ui/shared/forms/fields/FormFieldFancySelect
'
;
import
{
Checkbox
}
from
'
toolkit/chakra/checkbox
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
FormFieldSelect
from
'
ui/shared/forms/fields/FormFieldSelect
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
...
@@ -26,12 +26,15 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
...
@@ -26,12 +26,15 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
const
config
=
queryClient
.
getQueryData
<
SmartContractVerificationConfig
>
(
getResourceKey
(
'
contract_verification_config
'
));
const
config
=
queryClient
.
getQueryData
<
SmartContractVerificationConfig
>
(
getResourceKey
(
'
contract_verification_config
'
));
const
handleCheckboxChange
=
React
.
useCallback
(()
=>
{
const
handleCheckboxChange
=
React
.
useCallback
(()
=>
{
if
(
isNightly
)
{
setIsNightly
(
prev
=>
{
if
(
prev
)
{
const
field
=
getValues
(
'
compiler
'
);
const
field
=
getValues
(
'
compiler
'
);
field
?.
value
.
includes
(
'
nightly
'
)
&&
resetField
(
'
compiler
'
,
{
defaultValue
:
null
});
field
?.[
0
]?.
includes
(
'
nightly
'
)
&&
resetField
(
'
compiler
'
,
{
defaultValue
:
[]
});
}
}
setIsNightly
(
prev
=>
!
prev
);
},
[
getValues
,
isNightly
,
resetField
]);
return
!
prev
;
});
},
[
getValues
,
resetField
]);
const
options
=
React
.
useMemo
(()
=>
{
const
options
=
React
.
useMemo
(()
=>
{
const
versions
=
(()
=>
{
const
versions
=
(()
=>
{
...
@@ -47,11 +50,21 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
...
@@ -47,11 +50,21 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
return
versions
?.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}))
||
[];
return
versions
?.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}))
||
[];
},
[
isStylus
,
isVyper
,
config
?.
solidity_compiler_versions
,
config
?.
stylus_compiler_versions
,
config
?.
vyper_compiler_versions
]);
},
[
isStylus
,
isVyper
,
config
?.
solidity_compiler_versions
,
config
?.
stylus_compiler_versions
,
config
?.
vyper_compiler_versions
]);
const
loadOptions
=
React
.
useCallback
(
async
(
inputValue
:
string
)
=>
{
// const loadOptions = React.useCallback(async(inputValue: string) => {
return
options
// return options
.
filter
(({
label
})
=>
!
inputValue
||
label
.
toLowerCase
().
includes
(
inputValue
.
toLowerCase
()))
// .filter(({ label }) => !inputValue || label.toLowerCase().includes(inputValue.toLowerCase()))
// .filter(({ label }) => isNightly ? true : !label.includes('nightly'))
// .slice(0, OPTIONS_LIMIT);
// }, [ isNightly, options ]);
// TODO @tom2drum implement filtering the options
const
collection
=
React
.
useMemo
(()
=>
{
const
items
=
options
// .filter(({ label }) => !inputValue || label.toLowerCase().includes(inputValue.toLowerCase()))
.
filter
(({
label
})
=>
isNightly
?
true
:
!
label
.
includes
(
'
nightly
'
))
.
filter
(({
label
})
=>
isNightly
?
true
:
!
label
.
includes
(
'
nightly
'
))
.
slice
(
0
,
OPTIONS_LIMIT
);
.
slice
(
0
,
OPTIONS_LIMIT
);
return
createListCollection
({
items
});
},
[
isNightly
,
options
]);
},
[
isNightly
,
options
]);
return
(
return
(
...
@@ -59,22 +72,19 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
...
@@ -59,22 +72,19 @@ const ContractVerificationFieldCompiler = ({ isVyper, isStylus }: Props) => {
<>
<>
{
!
isVyper
&&
!
isStylus
&&
(
{
!
isVyper
&&
!
isStylus
&&
(
<
Checkbox
<
Checkbox
size=
"lg"
mb=
{
2
}
mb=
{
2
}
onChange=
{
handleCheckboxChange
}
checked=
{
isNightly
}
isDisabled=
{
formState
.
isSubmitting
}
onCheckedChange=
{
handleCheckboxChange
}
disabled=
{
formState
.
isSubmitting
}
>
>
Include nightly builds
Include nightly builds
</
Checkbox
>
</
Checkbox
>
)
}
)
}
<
FormField
Fancy
Select
<
FormFields
,
'
compiler
'
>
<
FormFieldSelect
<
FormFields
,
'
compiler
'
>
name="compiler"
name="compiler"
placeholder="Compiler (enter version or use the dropdown)"
placeholder="Compiler (enter version or use the dropdown)"
loadOptions=
{
loadOptions
}
collection=
{
collection
}
defaultOptions
required
placeholderIcon=
{
<
IconSvg
name=
"search"
/>
}
isRequired
isAsync
/
>
/
>
</>
</>
{
isVyper
||
isStylus
?
null
:
(
{
isVyper
||
isStylus
?
null
:
(
...
...
ui/contractVerification/fields/ContractVerificationFieldConstructorArgs.tsx
View file @
532f7e7a
import
{
Link
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
...
@@ -12,10 +12,9 @@ const ContractVerificationFieldConstructorArgs = () => {
...
@@ -12,10 +12,9 @@ const ContractVerificationFieldConstructorArgs = () => {
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldText
<
FormFields
>
<
FormFieldText
<
FormFields
>
name="constructor_args"
name="constructor_args"
isR
equired
r
equired
rules=
{
{
maxLength
:
255
}
}
rules=
{
{
maxLength
:
255
}
}
placeholder="ABI-encoded Constructor Arguments"
placeholder="ABI-encoded Constructor Arguments"
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
asComponent="Textarea"
asComponent="Textarea"
/
>
/
>
<>
<>
...
...
ui/contractVerification/fields/ContractVerificationFieldEvmVersion.tsx
View file @
532f7e7a
import
{
Link
}
from
'
@chakra-ui/react
'
;
import
{
createListCollection
}
from
'
@chakra-ui/react
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
{
useQueryClient
}
from
'
@tanstack/react-query
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -6,7 +6,8 @@ import type { FormFields } from '../types';
...
@@ -6,7 +6,8 @@ import type { FormFields } from '../types';
import
type
{
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
type
{
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
{
getResourceKey
}
from
'
lib/api/useApiQuery
'
;
import
FormFieldFancySelect
from
'
ui/shared/forms/fields/FormFieldFancySelect
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
FormFieldSelect
from
'
ui/shared/forms/fields/FormFieldSelect
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
...
@@ -18,17 +19,19 @@ const ContractVerificationFieldEvmVersion = ({ isVyper }: Props) => {
...
@@ -18,17 +19,19 @@ const ContractVerificationFieldEvmVersion = ({ isVyper }: Props) => {
const
queryClient
=
useQueryClient
();
const
queryClient
=
useQueryClient
();
const
config
=
queryClient
.
getQueryData
<
SmartContractVerificationConfig
>
(
getResourceKey
(
'
contract_verification_config
'
));
const
config
=
queryClient
.
getQueryData
<
SmartContractVerificationConfig
>
(
getResourceKey
(
'
contract_verification_config
'
));
const
options
=
React
.
useMemo
(()
=>
(
const
collection
=
React
.
useMemo
(()
=>
{
(
isVyper
?
config
?.
vyper_evm_versions
:
config
?.
solidity_evm_versions
)?.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}))
||
[]
const
items
=
(
isVyper
?
config
?.
vyper_evm_versions
:
config
?.
solidity_evm_versions
)?.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}))
||
[];
),
[
config
?.
solidity_evm_versions
,
config
?.
vyper_evm_versions
,
isVyper
]);
return
createListCollection
({
items
});
},
[
config
?.
solidity_evm_versions
,
config
?.
vyper_evm_versions
,
isVyper
]);
return
(
return
(
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormField
Fancy
Select
<
FormFields
,
'
evm_version
'
>
<
FormFieldSelect
<
FormFields
,
'
evm_version
'
>
name="evm_version"
name="evm_version"
placeholder="EVM Version"
placeholder="EVM Version"
options=
{
options
}
collection=
{
collection
}
isR
equired
r
equired
/
>
/
>
<>
<>
<
span
>
The EVM version the contract is written for. If the bytecode does not match the version, we try to verify using the latest EVM version.
</
span
>
<
span
>
The EVM version the contract is written for. If the bytecode does not match the version, we try to verify using the latest EVM version.
</
span
>
...
...
ui/contractVerification/fields/ContractVerificationFieldLibraries.tsx
View file @
532f7e7a
import
{
Checkbox
,
useUpdateEffect
}
from
'
@chakra-ui/react
'
;
import
{
useUpdateEffect
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
useFieldArray
,
useFormContext
}
from
'
react-hook-form
'
;
import
{
useFieldArray
,
useFormContext
}
from
'
react-hook-form
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
{
Checkbox
}
from
'
toolkit/chakra/checkbox
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFieldLibraryItem
from
'
./ContractVerificationFieldLibraryItem
'
;
import
ContractVerificationFieldLibraryItem
from
'
./ContractVerificationFieldLibraryItem
'
;
...
@@ -44,10 +46,9 @@ const ContractVerificationFieldLibraries = () => {
...
@@ -44,10 +46,9 @@ const ContractVerificationFieldLibraries = () => {
<>
<>
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
Checkbox
<
Checkbox
size=
"lg"
onChange=
{
handleCheckboxChange
}
onChange=
{
handleCheckboxChange
}
mt=
{
9
}
mt=
{
9
}
isD
isabled=
{
formState
.
isSubmitting
}
d
isabled=
{
formState
.
isSubmitting
}
>
>
Add contract libraries
Add contract libraries
</
Checkbox
>
</
Checkbox
>
...
...
ui/contractVerification/fields/ContractVerificationFieldLibraryItem.tsx
View file @
532f7e7a
import
{
Flex
,
IconButton
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
FormFieldAddress
from
'
ui/shared/forms/fields/FormFieldAddress
'
;
import
FormFieldAddress
from
'
ui/shared/forms/fields/FormFieldAddress
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
@@ -38,7 +39,7 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
...
@@ -38,7 +39,7 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
<>
<>
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
ref=
{
ref
}
mt=
{
index
!==
0
?
6
:
0
}
>
<
Flex
alignItems=
"center"
justifyContent=
"space-between"
ref=
{
ref
}
mt=
{
index
!==
0
?
6
:
0
}
>
<
Text
variant=
"
secondary"
fontSize=
"sm"
>
Contract library
{
index
+
1
}
</
Text
>
<
Text
color=
"text.
secondary"
fontSize=
"sm"
>
Contract library
{
index
+
1
}
</
Text
>
<
Flex
columnGap=
{
5
}
>
<
Flex
columnGap=
{
5
}
>
{
fieldsLength
>
1
&&
(
{
fieldsLength
>
1
&&
(
<
IconButton
<
IconButton
...
@@ -47,9 +48,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
...
@@ -47,9 +48,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
w=
"30px"
w=
"30px"
h=
"30px"
h=
"30px"
onClick=
{
handleRemoveButtonClick
}
onClick=
{
handleRemoveButtonClick
}
icon=
{
<
IconSvg
name=
"minus"
w=
"20px"
h=
"20px"
/>
}
disabled=
{
isDisabled
}
isDisabled=
{
isDisabled
}
>
/>
<
IconSvg
name=
"minus"
w=
"20px"
h=
"20px"
/>
</
IconButton
>
)
}
)
}
{
fieldsLength
<
LIMIT
&&
(
{
fieldsLength
<
LIMIT
&&
(
<
IconButton
<
IconButton
...
@@ -58,9 +60,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
...
@@ -58,9 +60,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
w=
"30px"
w=
"30px"
h=
"30px"
h=
"30px"
onClick=
{
handleAddButtonClick
}
onClick=
{
handleAddButtonClick
}
icon=
{
<
IconSvg
name=
"plus"
w=
"20px"
h=
"20px"
/>
}
disabled=
{
isDisabled
}
isDisabled=
{
isDisabled
}
>
/>
<
IconSvg
name=
"plus"
w=
"20px"
h=
"20px"
/>
</
IconButton
>
)
}
)
}
</
Flex
>
</
Flex
>
</
Flex
>
</
Flex
>
...
@@ -68,10 +71,9 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
...
@@ -68,10 +71,9 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldText
<
FormFields
,
`
libraries
.
$
{
number
}
.
name
`
>
<
FormFieldText
<
FormFields
,
`
libraries
.
$
{
number
}
.
name
`
>
name=
{
`libraries.${ index }.name`
}
name=
{
`libraries.${ index }.name`
}
isR
equired
r
equired
rules=
{
{
maxLength
:
255
}
}
rules=
{
{
maxLength
:
255
}
}
placeholder="Library name (.sol file)"
placeholder="Library name (.sol file)"
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
/
>
/
>
{
index
===
0
?
(
{
index
===
0
?
(
<>
<>
...
@@ -80,11 +82,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
...
@@ -80,11 +82,10 @@ const ContractVerificationFieldLibraryItem = ({ index, fieldsLength, onAddFieldC
)
:
null
}
)
:
null
}
</
ContractVerificationFormRow
>
</
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldAddress
<
FormFields
,
`
libraries
.
$
{
number
}
.
address
`
>
<
FormFieldAddress
<
FormFields
>
name=
{
`libraries.${ index }.address`
}
name=
{
`libraries.${ index }.address`
}
isR
equired
r
equired
placeholder="Library address (0x...)"
placeholder="Library address (0x...)"
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
/
>
/
>
{
index
===
0
?
(
{
index
===
0
?
(
<>
<>
...
...
ui/contractVerification/fields/ContractVerificationFieldLicenseType.tsx
View file @
532f7e7a
import
{
createListCollection
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
{
CONTRACT_LICENSES
}
from
'
lib/contracts/licenses
'
;
import
{
CONTRACT_LICENSES
}
from
'
lib/contracts/licenses
'
;
import
FormField
FancySelect
from
'
ui/shared/forms/fields/FormFieldFancy
Select
'
;
import
FormField
Select
from
'
ui/shared/forms/fields/FormField
Select
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
import
ContractVerificationFormRow
from
'
../ContractVerificationFormRow
'
;
const
options
=
CONTRACT_LICENSES
.
map
(({
label
,
title
,
type
})
=>
({
label
:
`
${
title
}
(
${
label
}
)`
,
value
:
type
}));
const
collection
=
createListCollection
({
items
:
CONTRACT_LICENSES
.
map
(({
label
,
title
,
type
})
=>
({
label
:
`
${
title
}
(
${
label
}
)`
,
value
:
type
})),
});
const
ContractVerificationFieldLicenseType
=
()
=>
{
const
ContractVerificationFieldLicenseType
=
()
=>
{
return
(
return
(
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormField
Fancy
Select
<
FormFields
,
'
license_type
'
>
<
FormFieldSelect
<
FormFields
,
'
license_type
'
>
name="license_type"
name="license_type"
placeholder="Contract license"
placeholder="Contract license"
options=
{
options
}
collection=
{
collection
}
/
>
/
>
<
span
>
<
span
>
For best practices, all contract source code holders, publishers and authors are encouraged to also
For best practices, all contract source code holders, publishers and authors are encouraged to also
...
...
ui/contractVerification/fields/ContractVerificationFieldMethod.tsx
View file @
532f7e7a
import
{
import
{
Link
,
chakra
,
chakra
,
PopoverTrigger
,
List
,
Portal
,
PopoverContent
,
PopoverArrow
,
PopoverBody
,
useColorModeValue
,
DarkMode
,
ListItem
,
OrderedList
,
Box
,
Box
,
createListCollection
,
}
from
'
@chakra-ui/react
'
;
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
FormFields
}
from
'
../types
'
;
import
type
{
SmartContractVerificationMethod
,
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
type
{
SmartContractVerificationMethod
,
SmartContractVerificationConfig
}
from
'
types/client/contract
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
FormField
FancySelect
from
'
ui/shared/forms/fields/FormFieldFancy
Select
'
;
import
FormField
Select
from
'
ui/shared/forms/fields/FormField
Select
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
{
METHOD_LABELS
}
from
'
../utils
'
;
import
{
METHOD_LABELS
}
from
'
../utils
'
;
...
@@ -29,95 +21,87 @@ interface Props {
...
@@ -29,95 +21,87 @@ interface Props {
}
}
const
ContractVerificationFieldMethod
=
({
methods
}:
Props
)
=>
{
const
ContractVerificationFieldMethod
=
({
methods
}:
Props
)
=>
{
const
tooltipBg
=
useColorModeValue
(
'
gray.700
'
,
'
gray.900
'
);
const
collection
=
React
.
useMemo
(()
=>
createListCollection
({
const
isMobile
=
useIsMobile
();
items
:
methods
.
map
((
method
)
=>
({
const
options
=
React
.
useMemo
(()
=>
methods
.
map
((
method
)
=>
({
value
:
method
,
value
:
method
,
label
:
METHOD_LABELS
[
method
],
label
:
METHOD_LABELS
[
method
],
})),
[
methods
]);
})),
}),
[
methods
]);
const
renderPopoverListItem
=
React
.
useCallback
((
method
:
SmartContractVerificationMethod
)
=>
{
const
renderPopoverListItem
=
React
.
useCallback
((
method
:
SmartContractVerificationMethod
)
=>
{
switch
(
method
)
{
switch
(
method
)
{
case
'
flattened-code
'
:
case
'
flattened-code
'
:
return
<
List
Item
key=
{
method
}
>
Verification through a single file.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification through a single file.
</
List
.
Item
>;
case
'
multi-part
'
:
case
'
multi-part
'
:
return
<
List
Item
key=
{
method
}
>
Verification of multi-part Solidity files.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification of multi-part Solidity files.
</
List
.
Item
>;
case
'
sourcify
'
:
case
'
sourcify
'
:
return
<
List
Item
key=
{
method
}
>
Verification through
<
Link
href=
"https://sourcify.dev/"
target=
"_blank"
>
Sourcify
</
Link
>
.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification through
<
Link
href=
"https://sourcify.dev/"
target=
"_blank"
className=
"dark"
>
Sourcify
</
Link
>
.
</
List
.
Item
>;
case
'
standard-input
'
:
case
'
standard-input
'
:
return
(
return
(
<
ListItem
key=
{
method
}
>
<
List
.
Item
key=
{
method
}
>
<
span
>
Verification using
</
span
>
<
span
>
Verification using
</
span
>
<
Link
<
Link
href=
"https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description"
href=
"https://docs.soliditylang.org/en/latest/using-the-compiler.html#input-description"
target=
"_blank"
target=
"_blank"
className=
"dark"
>
>
Standard input JSON
Standard input JSON
</
Link
>
</
Link
>
<
span
>
file.
</
span
>
<
span
>
file.
</
span
>
</
ListItem
>
</
List
.
Item
>
);
);
case
'
vyper-code
'
:
case
'
vyper-code
'
:
return
<
List
Item
key=
{
method
}
>
Verification of Vyper contract.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification of Vyper contract.
</
List
.
Item
>;
case
'
vyper-multi-part
'
:
case
'
vyper-multi-part
'
:
return
<
List
Item
key=
{
method
}
>
Verification of multi-part Vyper files.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification of multi-part Vyper files.
</
List
.
Item
>;
case
'
vyper-standard-input
'
:
case
'
vyper-standard-input
'
:
return
(
return
(
<
ListItem
key=
{
method
}
>
<
List
.
Item
key=
{
method
}
>
<
span
>
Verification of Vyper contract using
</
span
>
<
span
>
Verification of Vyper contract using
</
span
>
<
Link
<
Link
href=
"https://docs.vyperlang.org/en/stable/compiling-a-contract.html#compiler-input-and-output-json-description"
href=
"https://docs.vyperlang.org/en/stable/compiling-a-contract.html#compiler-input-and-output-json-description"
target=
"_blank"
target=
"_blank"
className=
"dark"
>
>
Standard input JSON
Standard input JSON
</
Link
>
</
Link
>
<
span
>
file.
</
span
>
<
span
>
file.
</
span
>
</
ListItem
>
</
List
.
Item
>
);
);
case
'
solidity-hardhat
'
:
case
'
solidity-hardhat
'
:
return
<
List
Item
key=
{
method
}
>
Verification through Hardhat plugin.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification through Hardhat plugin.
</
List
.
Item
>;
case
'
solidity-foundry
'
:
case
'
solidity-foundry
'
:
return
<
List
Item
key=
{
method
}
>
Verification through Foundry.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification through Foundry.
</
List
.
Item
>;
case
'
stylus-github-repository
'
:
case
'
stylus-github-repository
'
:
return
<
List
Item
key=
{
method
}
>
Verification of Stylus contract via GitHub repository.
</
List
Item
>;
return
<
List
.
Item
key=
{
method
}
>
Verification of Stylus contract via GitHub repository.
</
List
.
Item
>;
}
}
},
[]);
},
[]);
const
tooltipContent
=
(
<
Box
>
<
span
>
Currently, Blockscout supports
{
methods
.
length
}
methods:
</
span
>
<
List
.
Root
as=
"ol"
pl=
{
5
}
>
{
methods
.
map
(
renderPopoverListItem
)
}
</
List
.
Root
>
</
Box
>
);
return
(
return
(
<>
<>
<
Box
mt=
{
{
base
:
10
,
lg
:
6
}
}
gridColumn=
{
{
lg
:
'
1 / 3
'
}
}
>
<
Box
mt=
{
{
base
:
10
,
lg
:
6
}
}
gridColumn=
{
{
lg
:
'
1 / 3
'
}
}
>
<
chakra
.
span
fontWeight=
{
500
}
fontSize=
"lg"
fontFamily=
"heading"
>
<
chakra
.
span
fontWeight=
{
500
}
fontSize=
"lg"
fontFamily=
"heading"
>
Currently, Blockscout supports
{
methods
.
length
}
contract verification methods
Currently, Blockscout supports
{
methods
.
length
}
contract verification methods
</
chakra
.
span
>
</
chakra
.
span
>
<
Popover
trigger=
"hover"
isLazy
placement=
{
isMobile
?
'
bottom-end
'
:
'
right-start
'
}
offset=
{
[
-
8
,
8
]
}
>
<
Tooltip
content=
{
tooltipContent
}
interactive
contentProps=
{
{
textAlign
:
'
left
'
,
className
:
'
light
'
}
}
>
<
PopoverTrigger
>
<
IconSvg
name=
"info"
boxSize=
{
5
}
ml=
{
1
}
cursor=
"pointer"
color=
"icon.info"
_hover=
{
{
color
:
'
link.primary.hover
'
}
}
/>
<
chakra
.
span
display=
"inline-block"
ml=
{
1
}
cursor=
"pointer"
verticalAlign=
"middle"
h=
"22px"
>
</
Tooltip
>
<
IconSvg
name=
"info"
boxSize=
{
5
}
color=
"icon_info"
_hover=
{
{
color
:
'
link_hovered
'
}
}
/>
</
chakra
.
span
>
</
PopoverTrigger
>
<
Portal
>
<
PopoverContent
bgColor=
{
tooltipBg
}
w=
{
{
base
:
'
300px
'
,
lg
:
'
380px
'
}
}
>
<
PopoverArrow
bgColor=
{
tooltipBg
}
/>
<
PopoverBody
color=
"white"
>
<
DarkMode
>
<
span
>
Currently, Blockscout supports
{
methods
.
length
}
methods:
</
span
>
<
OrderedList
>
{
methods
.
map
(
renderPopoverListItem
)
}
</
OrderedList
>
</
DarkMode
>
</
PopoverBody
>
</
PopoverContent
>
</
Portal
>
</
Popover
>
</
Box
>
</
Box
>
<
FormField
Fancy
Select
<
FormFields
,
'
method
'
>
<
FormFieldSelect
<
FormFields
,
'
method
'
>
name="method"
name="method"
placeholder="Verification method (compiler type)"
placeholder="Verification method (compiler type)"
options=
{
options
}
collection=
{
collection
}
isRequired
required
isAsync=
{
false
}
readOnly=
{
collection
.
items
.
length
===
1
}
isReadOnly=
{
options
.
length
===
1
}
/
>
/
>
</>
</>
);
);
...
...
ui/contractVerification/fields/ContractVerificationFieldName.tsx
View file @
532f7e7a
...
@@ -16,9 +16,8 @@ const ContractVerificationFieldName = ({ hint }: Props) => {
...
@@ -16,9 +16,8 @@ const ContractVerificationFieldName = ({ hint }: Props) => {
<
ContractVerificationFormRow
>
<
ContractVerificationFormRow
>
<
FormFieldText
<
FormFields
>
<
FormFieldText
<
FormFields
>
name="name"
name="name"
isR
equired
r
equired
placeholder="Contract name"
placeholder="Contract name"
size=
{
{
base
:
'
md
'
,
lg
:
'
lg
'
}
}
rules=
{
{
maxLength
:
255
}
}
rules=
{
{
maxLength
:
255
}
}
/
>
/
>
{
hint
?
<
span
>
{
hint
}
</
span
>
:
(
{
hint
?
<
span
>
{
hint
}
</
span
>
:
(
...
...
ui/contractVerification/fields/ContractVerificationFieldOptimization.tsx
View file @
532f7e7a
...
@@ -27,10 +27,12 @@ const ContractVerificationFieldOptimization = () => {
...
@@ -27,10 +27,12 @@ const ContractVerificationFieldOptimization = () => {
{
isEnabled
&&
(
{
isEnabled
&&
(
<
FormFieldText
<
FormFields
,
'
optimization_runs
'
>
<
FormFieldText
<
FormFields
,
'
optimization_runs
'
>
name="optimization_runs"
name="optimization_runs"
isR
equired
r
equired
placeholder="Optimization runs"
placeholder="Optimization runs"
type="number"
inputProps=
{
{
size="xs"
type
:
'
number
'
,
}
}
size="sm"
minW="100px"
minW="100px"
maxW="200px"
maxW="200px"
flexShrink=
{
1
}
flexShrink=
{
1
}
...
...
ui/contractVerification/types.ts
View file @
532f7e7a
...
@@ -7,11 +7,6 @@ export interface ContractLibrary {
...
@@ -7,11 +7,6 @@ export interface ContractLibrary {
address
:
string
;
address
:
string
;
}
}
interface
MethodOption
{
label
:
string
;
value
:
SmartContractVerificationMethod
;
}
export
interface
LicenseOption
{
export
interface
LicenseOption
{
label
:
string
;
label
:
string
;
value
:
SmartContractLicenseType
;
value
:
SmartContractLicenseType
;
...
@@ -19,15 +14,15 @@ export interface LicenseOption {
...
@@ -19,15 +14,15 @@ export interface LicenseOption {
interface
FormFieldsBase
{
interface
FormFieldsBase
{
address
:
string
;
address
:
string
;
method
:
MethodOption
;
method
:
Array
<
SmartContractVerificationMethod
>
;
license_type
:
LicenseOption
|
null
;
license_type
:
Array
<
SmartContractLicenseType
>
;
}
}
export
interface
FormFieldsFlattenSourceCode
extends
FormFieldsBase
{
export
interface
FormFieldsFlattenSourceCode
extends
FormFieldsBase
{
is_yul
:
boolean
;
is_yul
:
boolean
;
name
:
string
|
undefined
;
name
:
string
|
undefined
;
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
evm_version
:
Option
|
null
;
evm_version
:
Array
<
string
>
;
is_optimization_enabled
:
boolean
;
is_optimization_enabled
:
boolean
;
optimization_runs
:
string
;
optimization_runs
:
string
;
code
:
string
;
code
:
string
;
...
@@ -38,7 +33,7 @@ export interface FormFieldsFlattenSourceCode extends FormFieldsBase {
...
@@ -38,7 +33,7 @@ export interface FormFieldsFlattenSourceCode extends FormFieldsBase {
export
interface
FormFieldsStandardInput
extends
FormFieldsBase
{
export
interface
FormFieldsStandardInput
extends
FormFieldsBase
{
name
:
string
;
name
:
string
;
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
sources
:
Array
<
File
>
;
sources
:
Array
<
File
>
;
autodetect_constructor_args
:
boolean
;
autodetect_constructor_args
:
boolean
;
constructor_args
:
string
;
constructor_args
:
string
;
...
@@ -46,8 +41,8 @@ export interface FormFieldsStandardInput extends FormFieldsBase {
...
@@ -46,8 +41,8 @@ export interface FormFieldsStandardInput extends FormFieldsBase {
export
interface
FormFieldsStandardInputZk
extends
FormFieldsBase
{
export
interface
FormFieldsStandardInputZk
extends
FormFieldsBase
{
name
:
string
;
name
:
string
;
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
zk_compiler
:
Option
|
null
;
zk_compiler
:
Array
<
string
>
;
sources
:
Array
<
File
>
;
sources
:
Array
<
File
>
;
autodetect_constructor_args
:
boolean
;
autodetect_constructor_args
:
boolean
;
constructor_args
:
string
;
constructor_args
:
string
;
...
@@ -59,8 +54,8 @@ export interface FormFieldsSourcify extends FormFieldsBase {
...
@@ -59,8 +54,8 @@ export interface FormFieldsSourcify extends FormFieldsBase {
}
}
export
interface
FormFieldsMultiPartFile
extends
FormFieldsBase
{
export
interface
FormFieldsMultiPartFile
extends
FormFieldsBase
{
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
evm_version
:
Option
|
null
;
evm_version
:
Array
<
string
>
;
is_optimization_enabled
:
boolean
;
is_optimization_enabled
:
boolean
;
optimization_runs
:
string
;
optimization_runs
:
string
;
sources
:
Array
<
File
>
;
sources
:
Array
<
File
>
;
...
@@ -69,26 +64,26 @@ export interface FormFieldsMultiPartFile extends FormFieldsBase {
...
@@ -69,26 +64,26 @@ export interface FormFieldsMultiPartFile extends FormFieldsBase {
export
interface
FormFieldsVyperContract
extends
FormFieldsBase
{
export
interface
FormFieldsVyperContract
extends
FormFieldsBase
{
name
:
string
;
name
:
string
;
evm_version
:
Option
|
null
;
evm_version
:
Array
<
string
>
;
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
code
:
string
;
code
:
string
;
constructor_args
:
string
|
undefined
;
constructor_args
:
string
|
undefined
;
}
}
export
interface
FormFieldsVyperMultiPartFile
extends
FormFieldsBase
{
export
interface
FormFieldsVyperMultiPartFile
extends
FormFieldsBase
{
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
evm_version
:
Option
|
null
;
evm_version
:
Array
<
string
>
;
sources
:
Array
<
File
>
;
sources
:
Array
<
File
>
;
interfaces
:
Array
<
File
>
;
interfaces
:
Array
<
File
>
;
}
}
export
interface
FormFieldsVyperStandardInput
extends
FormFieldsBase
{
export
interface
FormFieldsVyperStandardInput
extends
FormFieldsBase
{
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
sources
:
Array
<
File
>
;
sources
:
Array
<
File
>
;
}
}
export
interface
FormFieldsStylusGitHubRepo
extends
FormFieldsBase
{
export
interface
FormFieldsStylusGitHubRepo
extends
FormFieldsBase
{
compiler
:
Option
|
null
;
compiler
:
Array
<
string
>
;
repository_url
:
string
;
repository_url
:
string
;
commit_hash
:
string
;
commit_hash
:
string
;
path_prefix
:
string
;
path_prefix
:
string
;
...
...
ui/contractVerification/utils.ts
View file @
532f7e7a
...
@@ -51,123 +51,93 @@ export const METHOD_LABELS: Record<SmartContractVerificationMethod, string> = {
...
@@ -51,123 +51,93 @@ export const METHOD_LABELS: Record<SmartContractVerificationMethod, string> = {
export
const
DEFAULT_VALUES
:
Record
<
SmartContractVerificationMethod
,
FormFields
>
=
{
export
const
DEFAULT_VALUES
:
Record
<
SmartContractVerificationMethod
,
FormFields
>
=
{
'
flattened-code
'
:
{
'
flattened-code
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
flattened-code
'
],
value
:
'
flattened-code
'
as
const
,
label
:
METHOD_LABELS
[
'
flattened-code
'
],
},
is_yul
:
false
,
is_yul
:
false
,
name
:
''
,
name
:
''
,
compiler
:
null
,
compiler
:
[]
,
evm_version
:
null
,
evm_version
:
[]
,
is_optimization_enabled
:
true
,
is_optimization_enabled
:
true
,
optimization_runs
:
'
200
'
,
optimization_runs
:
'
200
'
,
code
:
''
,
code
:
''
,
autodetect_constructor_args
:
true
,
autodetect_constructor_args
:
true
,
constructor_args
:
''
,
constructor_args
:
''
,
libraries
:
[],
libraries
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
standard-input
'
:
{
'
standard-input
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
standard-input
'
],
value
:
'
standard-input
'
as
const
,
label
:
METHOD_LABELS
[
'
standard-input
'
],
},
name
:
''
,
name
:
''
,
compiler
:
null
,
compiler
:
[]
,
sources
:
[],
sources
:
[],
autodetect_constructor_args
:
true
,
autodetect_constructor_args
:
true
,
constructor_args
:
''
,
constructor_args
:
''
,
license_type
:
null
,
license_type
:
[]
,
},
},
sourcify
:
{
sourcify
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
sourcify
'
],
value
:
'
sourcify
'
as
const
,
label
:
METHOD_LABELS
.
sourcify
,
},
sources
:
[],
sources
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
multi-part
'
:
{
'
multi-part
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
multi-part
'
],
value
:
'
multi-part
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
multi-part
'
],
evm_version
:
[],
},
compiler
:
null
,
evm_version
:
null
,
is_optimization_enabled
:
true
,
is_optimization_enabled
:
true
,
optimization_runs
:
'
200
'
,
optimization_runs
:
'
200
'
,
sources
:
[],
sources
:
[],
libraries
:
[],
libraries
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
vyper-code
'
:
{
'
vyper-code
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
vyper-code
'
],
value
:
'
vyper-code
'
as
const
,
label
:
METHOD_LABELS
[
'
vyper-code
'
],
},
name
:
''
,
name
:
''
,
compiler
:
null
,
compiler
:
[]
,
evm_version
:
null
,
evm_version
:
[]
,
code
:
''
,
code
:
''
,
constructor_args
:
''
,
constructor_args
:
''
,
license_type
:
null
,
license_type
:
[]
,
},
},
'
vyper-multi-part
'
:
{
'
vyper-multi-part
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
vyper-multi-part
'
],
value
:
'
vyper-multi-part
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
vyper-multi-part
'
],
evm_version
:
[],
},
compiler
:
null
,
evm_version
:
null
,
sources
:
[],
sources
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
vyper-standard-input
'
:
{
'
vyper-standard-input
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
vyper-standard-input
'
],
value
:
'
vyper-standard-input
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
vyper-standard-input
'
],
},
compiler
:
null
,
sources
:
[],
sources
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
solidity-hardhat
'
:
{
'
solidity-hardhat
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
solidity-hardhat
'
],
value
:
'
solidity-hardhat
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
solidity-hardhat
'
],
},
compiler
:
null
,
sources
:
[],
sources
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
solidity-foundry
'
:
{
'
solidity-foundry
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
solidity-foundry
'
],
value
:
'
solidity-foundry
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
solidity-foundry
'
],
},
compiler
:
null
,
sources
:
[],
sources
:
[],
license_type
:
null
,
license_type
:
[]
,
},
},
'
stylus-github-repository
'
:
{
'
stylus-github-repository
'
:
{
address
:
''
,
address
:
''
,
method
:
{
method
:
[
'
stylus-github-repository
'
],
value
:
'
stylus-github-repository
'
as
const
,
compiler
:
[],
label
:
METHOD_LABELS
[
'
stylus-github-repository
'
],
},
compiler
:
null
,
repository_url
:
''
,
repository_url
:
''
,
commit_hash
:
''
,
commit_hash
:
''
,
path_prefix
:
''
,
path_prefix
:
''
,
license_type
:
null
,
license_type
:
[]
,
},
},
};
};
...
@@ -188,11 +158,11 @@ export function getDefaultValues(
...
@@ -188,11 +158,11 @@ export function getDefaultValues(
if
(
'
evm_version
'
in
defaultValues
)
{
if
(
'
evm_version
'
in
defaultValues
)
{
if
(
method
===
'
flattened-code
'
||
method
===
'
multi-part
'
)
{
if
(
method
===
'
flattened-code
'
||
method
===
'
multi-part
'
)
{
defaultValues
.
evm_version
=
config
.
solidity_evm_versions
.
find
((
value
)
=>
value
===
'
default
'
)
?
{
label
:
'
default
'
,
value
:
'
default
'
}
:
null
;
defaultValues
.
evm_version
=
config
.
solidity_evm_versions
.
find
((
value
)
=>
value
===
'
default
'
)
?
[
'
default
'
]
:
[]
;
}
}
if
(
method
===
'
vyper-multi-part
'
)
{
if
(
method
===
'
vyper-multi-part
'
)
{
defaultValues
.
evm_version
=
config
.
vyper_evm_versions
.
find
((
value
)
=>
value
===
'
default
'
)
?
{
label
:
'
default
'
,
value
:
'
default
'
}
:
null
;
defaultValues
.
evm_version
=
config
.
vyper_evm_versions
.
find
((
value
)
=>
value
===
'
default
'
)
?
[
'
default
'
]
:
[]
;
}
}
}
}
...
@@ -204,10 +174,7 @@ export function getDefaultValues(
...
@@ -204,10 +174,7 @@ export function getDefaultValues(
}
}
if
(
singleMethod
)
{
if
(
singleMethod
)
{
defaultValues
.
method
=
{
defaultValues
.
method
=
config
.
verification_options
;
label
:
METHOD_LABELS
[
config
.
verification_options
[
0
]],
value
:
config
.
verification_options
[
0
],
};
}
}
return
defaultValues
;
return
defaultValues
;
...
@@ -235,21 +202,21 @@ export function sortVerificationMethods(methodA: SmartContractVerificationMethod
...
@@ -235,21 +202,21 @@ export function sortVerificationMethods(methodA: SmartContractVerificationMethod
export
function
prepareRequestBody
(
data
:
FormFields
):
FetchParams
[
'
body
'
]
{
export
function
prepareRequestBody
(
data
:
FormFields
):
FetchParams
[
'
body
'
]
{
const
defaultLicenseType
:
SmartContractLicenseType
=
'
none
'
;
const
defaultLicenseType
:
SmartContractLicenseType
=
'
none
'
;
switch
(
data
.
method
.
value
)
{
switch
(
data
.
method
[
0
]
)
{
case
'
flattened-code
'
:
{
case
'
flattened-code
'
:
{
const
_data
=
data
as
FormFieldsFlattenSourceCode
;
const
_data
=
data
as
FormFieldsFlattenSourceCode
;
return
{
return
{
compiler_version
:
_data
.
compiler
?.
value
,
compiler_version
:
_data
.
compiler
?.
[
0
]
,
source_code
:
_data
.
code
,
source_code
:
_data
.
code
,
is_optimization_enabled
:
_data
.
is_optimization_enabled
,
is_optimization_enabled
:
_data
.
is_optimization_enabled
,
is_yul_contract
:
_data
.
is_yul
,
is_yul_contract
:
_data
.
is_yul
,
optimization_runs
:
_data
.
optimization_runs
,
optimization_runs
:
_data
.
optimization_runs
,
contract_name
:
_data
.
name
||
undefined
,
contract_name
:
_data
.
name
||
undefined
,
libraries
:
reduceLibrariesArray
(
_data
.
libraries
),
libraries
:
reduceLibrariesArray
(
_data
.
libraries
),
evm_version
:
_data
.
evm_version
?.
value
,
evm_version
:
_data
.
evm_version
?.
[
0
]
,
autodetect_constructor_args
:
_data
.
autodetect_constructor_args
,
autodetect_constructor_args
:
_data
.
autodetect_constructor_args
,
constructor_args
:
_data
.
constructor_args
,
constructor_args
:
_data
.
constructor_args
,
license_type
:
_data
.
license_type
?.
value
??
defaultLicenseType
,
license_type
:
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
,
};
};
}
}
...
@@ -257,15 +224,15 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -257,15 +224,15 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
(
FormFieldsStandardInput
|
FormFieldsStandardInputZk
);
const
_data
=
data
as
(
FormFieldsStandardInput
|
FormFieldsStandardInputZk
);
const
body
=
new
FormData
();
const
body
=
new
FormData
();
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
.
value
);
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
?.[
0
]
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
value
??
defaultLicenseType
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
);
body
.
set
(
'
contract_name
'
,
_data
.
name
);
body
.
set
(
'
contract_name
'
,
_data
.
name
);
body
.
set
(
'
autodetect_constructor_args
'
,
String
(
Boolean
(
_data
.
autodetect_constructor_args
)));
body
.
set
(
'
autodetect_constructor_args
'
,
String
(
Boolean
(
_data
.
autodetect_constructor_args
)));
body
.
set
(
'
constructor_args
'
,
_data
.
constructor_args
);
body
.
set
(
'
constructor_args
'
,
_data
.
constructor_args
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
// zkSync fields
// zkSync fields
'
zk_compiler
'
in
_data
&&
_data
.
zk_compiler
&&
body
.
set
(
'
zk_compiler_version
'
,
_data
.
zk_compiler
.
value
);
'
zk_compiler
'
in
_data
&&
_data
.
zk_compiler
&&
body
.
set
(
'
zk_compiler_version
'
,
_data
.
zk_compiler
?.[
0
]
);
return
body
;
return
body
;
}
}
...
@@ -274,8 +241,8 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -274,8 +241,8 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsSourcify
;
const
_data
=
data
as
FormFieldsSourcify
;
const
body
=
new
FormData
();
const
body
=
new
FormData
();
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
body
.
set
(
'
chosen_contract_index
'
,
_data
.
contract_index
?.
value
??
defaultLicenseType
);
body
.
set
(
'
chosen_contract_index
'
,
_data
.
contract_index
?.
value
??
'
0
'
);
_data
.
license_type
&&
body
.
set
(
'
license_type
'
,
_data
.
license_type
.
valu
e
);
_data
.
license_type
&&
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.[
0
]
??
defaultLicenseTyp
e
);
return
body
;
return
body
;
}
}
...
@@ -284,9 +251,9 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -284,9 +251,9 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsMultiPartFile
;
const
_data
=
data
as
FormFieldsMultiPartFile
;
const
body
=
new
FormData
();
const
body
=
new
FormData
();
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
.
value
);
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
?.[
0
]
);
_data
.
evm_version
&&
body
.
set
(
'
evm_version
'
,
_data
.
evm_version
.
value
);
_data
.
evm_version
&&
body
.
set
(
'
evm_version
'
,
_data
.
evm_version
?.[
0
]
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
value
??
defaultLicenseType
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
);
body
.
set
(
'
is_optimization_enabled
'
,
String
(
Boolean
(
_data
.
is_optimization_enabled
)));
body
.
set
(
'
is_optimization_enabled
'
,
String
(
Boolean
(
_data
.
is_optimization_enabled
)));
_data
.
is_optimization_enabled
&&
body
.
set
(
'
optimization_runs
'
,
_data
.
optimization_runs
);
_data
.
is_optimization_enabled
&&
body
.
set
(
'
optimization_runs
'
,
_data
.
optimization_runs
);
...
@@ -301,12 +268,12 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -301,12 +268,12 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsVyperContract
;
const
_data
=
data
as
FormFieldsVyperContract
;
return
{
return
{
compiler_version
:
_data
.
compiler
?.
value
,
compiler_version
:
_data
.
compiler
?.
[
0
]
,
evm_version
:
_data
.
evm_version
?.
value
,
evm_version
:
_data
.
evm_version
?.
[
0
]
,
source_code
:
_data
.
code
,
source_code
:
_data
.
code
,
contract_name
:
_data
.
name
,
contract_name
:
_data
.
name
,
constructor_args
:
_data
.
constructor_args
,
constructor_args
:
_data
.
constructor_args
,
license_type
:
_data
.
license_type
?.
value
??
defaultLicenseType
,
license_type
:
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
,
};
};
}
}
...
@@ -314,9 +281,9 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -314,9 +281,9 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsVyperMultiPartFile
;
const
_data
=
data
as
FormFieldsVyperMultiPartFile
;
const
body
=
new
FormData
();
const
body
=
new
FormData
();
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
.
value
);
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
?.[
0
]
);
_data
.
evm_version
&&
body
.
set
(
'
evm_version
'
,
_data
.
evm_version
.
value
);
_data
.
evm_version
&&
body
.
set
(
'
evm_version
'
,
_data
.
evm_version
?.[
0
]
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
value
??
defaultLicenseType
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
addFilesToFormData
(
body
,
_data
.
interfaces
,
'
interfaces
'
);
addFilesToFormData
(
body
,
_data
.
interfaces
,
'
interfaces
'
);
...
@@ -327,8 +294,8 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -327,8 +294,8 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsVyperStandardInput
;
const
_data
=
data
as
FormFieldsVyperStandardInput
;
const
body
=
new
FormData
();
const
body
=
new
FormData
();
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
.
value
);
_data
.
compiler
&&
body
.
set
(
'
compiler_version
'
,
_data
.
compiler
?.[
0
]
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
value
??
defaultLicenseType
);
body
.
set
(
'
license_type
'
,
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
addFilesToFormData
(
body
,
_data
.
sources
,
'
files
'
);
return
body
;
return
body
;
...
@@ -338,11 +305,11 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
...
@@ -338,11 +305,11 @@ export function prepareRequestBody(data: FormFields): FetchParams['body'] {
const
_data
=
data
as
FormFieldsStylusGitHubRepo
;
const
_data
=
data
as
FormFieldsStylusGitHubRepo
;
return
{
return
{
cargo_stylus_version
:
_data
.
compiler
?.
value
,
cargo_stylus_version
:
_data
.
compiler
?.
[
0
]
,
repository_url
:
_data
.
repository_url
,
repository_url
:
_data
.
repository_url
,
commit
:
_data
.
commit_hash
,
commit
:
_data
.
commit_hash
,
path_prefix
:
_data
.
path_prefix
,
path_prefix
:
_data
.
path_prefix
,
license_type
:
_data
.
license_type
?.
value
??
defaultLicenseType
,
license_type
:
_data
.
license_type
?.
[
0
]
??
defaultLicenseType
,
};
};
}
}
...
...
ui/pages/ContractVerificationForAddress.tsx
View file @
532f7e7a
...
@@ -93,6 +93,8 @@ const ContractVerificationForAddress = () => {
...
@@ -93,6 +93,8 @@ const ContractVerificationForAddress = () => {
fontSize=
"lg"
fontSize=
"lg"
fontWeight=
{
500
}
fontWeight=
{
500
}
mb=
{
12
}
mb=
{
12
}
w=
"min-content"
maxW=
"100%"
/>
/>
{
content
}
{
content
}
</>
</>
...
...
ui/pages/VerifiedAddresses.tsx
View file @
532f7e7a
...
@@ -207,8 +207,8 @@ const VerifiedAddresses = () => {
...
@@ -207,8 +207,8 @@ const VerifiedAddresses = () => {
Before starting, make sure that:
Before starting, make sure that:
</
chakra
.
p
>
</
chakra
.
p
>
<
List
.
Root
ml=
{
6
}
as=
"ol"
>
<
List
.
Root
ml=
{
6
}
as=
"ol"
>
<
List
.
Item
_marker=
{
{
color
:
'
inherit
'
}
}
>
The source code for the smart contract is deployed on “
{
config
.
chain
.
name
}
”.
</
List
.
Item
>
<
List
.
Item
>
The source code for the smart contract is deployed on “
{
config
.
chain
.
name
}
”.
</
List
.
Item
>
<
List
.
Item
_marker=
{
{
color
:
'
inherit
'
}
}
>
<
List
.
Item
>
<
span
>
The source code is verified (if not yet verified, you can use
</
span
>
<
span
>
The source code is verified (if not yet verified, you can use
</
span
>
<
Link
href=
"https://docs.blockscout.com/for-users/verifying-a-smart-contract"
target=
"_blank"
>
this tool
</
Link
>
<
Link
href=
"https://docs.blockscout.com/for-users/verifying-a-smart-contract"
target=
"_blank"
>
this tool
</
Link
>
<
span
>
).
</
span
>
<
span
>
).
</
span
>
...
...
ui/shared/forms/fields/FormFieldText.tsx
View file @
532f7e7a
...
@@ -31,10 +31,15 @@ const FormFieldText = <
...
@@ -31,10 +31,15 @@ const FormFieldText = <
group
,
group
,
inputProps
,
inputProps
,
asComponent
,
asComponent
,
size
=
asComponent
===
'
Textarea
'
?
'
2xl
'
:
'
xl
'
,
size
:
sizeProp
,
disabled
,
disabled
,
floating
:
floatingProp
,
...
restProps
...
restProps
}
: Props
<
FormFields
,
Name
>
) =
>
{
}
: Props
<
FormFields
,
Name
>
) =
>
{
const
defaultSize
=
asComponent
===
'
Textarea
'
?
'
2xl
'
:
'
xl
'
;
const
size
=
sizeProp
||
defaultSize
;
const
floating
=
floatingProp
!==
undefined
?
floatingProp
:
size
===
defaultSize
;
const
{
control
}
=
useFormContext
<
FormFields
>
();
const
{
control
}
=
useFormContext
<
FormFields
>
();
const
{
field
,
fieldState
,
formState
}
=
useController
<
FormFields
,
typeof
name
>
({
const
{
field
,
fieldState
,
formState
}
=
useController
<
FormFields
,
typeof
name
>
({
control
,
control
,
...
@@ -59,6 +64,8 @@ const FormFieldText = <
...
@@ -59,6 +64,8 @@ const FormFieldText = <
<
Input
<
Input
{
...
field
}
{
...
field
}
autoComplete=
"off"
autoComplete=
"off"
// for non-floating field label, we pass placeholder to the input component
placeholder=
{
!
floating
?
placeholder
:
undefined
}
{
...
inputProps
as
InputProps
}
{
...
inputProps
as
InputProps
}
onBlur=
{
handleBlur
}
onBlur=
{
handleBlur
}
/>
/>
...
@@ -75,12 +82,13 @@ const FormFieldText = <
...
@@ -75,12 +82,13 @@ const FormFieldText = <
return
(
return
(
<
Field
<
Field
label=
{
placeholder
}
// for floating field label, we pass placeholder value to the label
label=
{
floating
?
placeholder
:
undefined
}
errorText=
{
getFieldErrorText
(
fieldState
.
error
)
}
errorText=
{
getFieldErrorText
(
fieldState
.
error
)
}
invalid=
{
Boolean
(
fieldState
.
error
)
}
invalid=
{
Boolean
(
fieldState
.
error
)
}
disabled=
{
formState
.
isSubmitting
||
disabled
}
disabled=
{
formState
.
isSubmitting
||
disabled
}
size=
{
size
}
size=
{
size
}
floating
floating
=
{
floating
}
{
...
restProps
}
{
...
restProps
}
>
>
{
content
}
{
content
}
...
...
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