Merge pull request #3843 from ethereum/tooltipVerify

styles -> bootstrap classes
pull/3840/head
yann300 1 year ago committed by GitHub
commit 5716685087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      apps/etherscan/src/app/components/HeaderWithSettings.tsx
  2. 55
      apps/etherscan/src/app/components/SubmitButton.tsx
  3. 17
      apps/etherscan/src/app/logo.svg
  4. 39
      apps/etherscan/src/app/routes.tsx
  5. 11
      apps/etherscan/src/app/star.svg
  6. 329
      apps/etherscan/src/app/utils/verify.ts
  7. 5
      apps/etherscan/src/app/views/CaptureKeyView.tsx
  8. 15
      apps/etherscan/src/app/views/ErrorView.tsx
  9. 1
      apps/etherscan/src/app/views/HomeView.tsx
  10. 44
      apps/etherscan/src/app/views/ReceiptsView.tsx
  11. 27
      apps/etherscan/src/app/views/VerifyView.tsx
  12. 2
      libs/remix-ui/plugin-manager/src/lib/components/rootView.tsx

@ -6,7 +6,6 @@ import { AppContext } from "../AppContext"
interface Props {
title?: string
showBackButton?: boolean
from: string
}
@ -16,42 +15,43 @@ interface IconProps {
const HomeIcon: React.FC<IconProps> = ({ from }: IconProps) => {
return (
<NavLink
data-id="home"
to={{
pathname: "/"
}}
state={ from }
<NavLink
data-id="home"
to={{
pathname: "/"
}}
className={({ isActive }) => isActive ? "btn p-0 m-0" : "btn text-dark p-0 m-0"}
state={ from }
>
<CustomTooltip
tooltipText='Home'
tooltipId='etherscan-nav-home'
placement='bottom'
>
<CustomTooltip
tooltipText='Home'
tooltipId='etherscan-nav-home'
placement='bottom'
>
<i className="fas fa-home"></i>
</CustomTooltip>
</NavLink>
<i className="fas fa-home"></i>
</CustomTooltip>
</NavLink>
)
}
const ReceiptsIcon: React.FC<IconProps> = ({ from }: IconProps) => {
return (
<NavLink
data-id="receipts"
to={{
pathname: "/receipts"
}}
state={ from }
className="mx-2"
<NavLink
data-id="receipts"
to={{
pathname: "/receipts"
}}
className={({ isActive }) => isActive ? "btn p-0 m-0 mx-2" : "btn text-dark p-0 m-0 mx-2"}
state={ from }
>
<CustomTooltip
tooltipText='Receipts'
tooltipId='etherscan-nav-receipts'
placement='bottom'
>
<CustomTooltip
tooltipText='Receipts'
tooltipId='etherscan-nav-receipts'
placement='bottom'
>
<i className="fas fa-receipt"></i>
</CustomTooltip>
</NavLink>
<i className="fas fa-receipt"></i>
</CustomTooltip>
</NavLink>
)
}
@ -62,6 +62,7 @@ const SettingsIcon: React.FC<IconProps> = ({ from }: IconProps) => {
to={{
pathname: "/settings"
}}
className={({ isActive }) => isActive ? "btn p-0 m-0" : "btn text-dark p-0 m-0"}
state= {from}
>
<CustomTooltip
@ -77,15 +78,14 @@ const SettingsIcon: React.FC<IconProps> = ({ from }: IconProps) => {
export const HeaderWithSettings: React.FC<Props> = ({
title = "",
showBackButton = false,
from,
}) => {
return (
<AppContext.Consumer>
{() => (
<div>
<div className="d-flex justify-content-between">
<h6 className="d-inline">{title}</h6>
<div style={{ float: "right" }}>
<div>
<HomeIcon from={from} />
<ReceiptsIcon from={from} />
<SettingsIcon from={from} />

@ -15,33 +15,34 @@ export const SubmitButton: React.FC<Props> = ({
disable = true
}) => {
return (
<CustomTooltip
tooltipText={disable ? "Fill the fields with valid values" : "Click to proceed"}
tooltipId='etherscan-submit-button'
placement='bottom'
>
<div>
<button
data-id={dataId}
style={{ padding: "0.25rem 0.4rem", marginRight: "0.5em" }}
type="submit"
className="btn btn-primary btn-block text-decoration-none"
disabled={disable}
<div>
<button
data-id={dataId}
type="submit"
className="btn btn-primary btn-block p-1 text-decoration-none"
disabled={disable}
>
<CustomTooltip
tooltipText={disable ? "Fill the fields with valid values" : "Click to proceed"}
tooltipId={'etherscan-submit-button-'+ dataId}
tooltipTextClasses="border bg-light text-dark p-1 pr-3"
placement='bottom'
>
{!isSubmitting && text}
{isSubmitting && (
<div>
<span
className="spinner-border spinner-border-sm"
role="status"
aria-hidden="true"
style={{ marginRight: "0.3em" }}
/>
Verifying... Please wait
</div>
)}
</button>
</div>
</CustomTooltip>
<div>
{!isSubmitting && text}
{isSubmitting && (
<div>
<span
className="spinner-border spinner-border-sm mr-1"
role="status"
aria-hidden="true"
/>
Verifying... Please wait
</div>
)}
</div>
</CustomTooltip>
</button>
</div>
)
}

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="262px" height="163px" viewBox="0 0 262 163" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Styles-&amp;-Quick-Wins" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Nx---Quick-Wins" transform="translate(-476.000000, -1284.000000)" fill-rule="nonzero">
<g id="Logos" transform="translate(-11.000000, 782.000000)">
<g id="Nx_Flat_White" transform="translate(487.000000, 502.000000)">
<polygon id="Path" fill="#FFFFFF" points="130.68 104.59 97.49 52.71 97.44 96.3 40.24 0 0 0 0 162.57 39.79 162.57 39.92 66.39 96.53 158.26"></polygon>
<polygon id="Path" fill="#FFFFFF" points="97.5 41.79 137.24 41.79 137.33 41.33 137.33 0 97.54 0 97.49 41.33"></polygon>
<path d="M198.66,86.86 C189.139872,86.6795216 180.538723,92.516445 177.19,101.43 C182.764789,93.0931021 193.379673,89.7432211 202.73,93.37 C207.05,95.13 212.73,97.97 217.23,96.45 C212.950306,90.4438814 206.034895,86.8725952 198.66,86.86 L198.66,86.86 Z" id="Path" fill="#96D8E9"></path>
<path d="M243.75,106.42 C243.75,101.55 241.1,100.42 235.6,98.42 C231.52,97 226.89,95.4 223.52,91 C222.86,90.13 222.25,89.15 221.6,88.11 C220.14382,85.4164099 218.169266,83.037429 215.79,81.11 C212.58,78.75 208.37,77.6 202.91,77.6 C191.954261,77.6076705 182.084192,84.2206169 177.91,94.35 C183.186964,87.0278244 191.956716,83.0605026 200.940147,83.9314609 C209.923578,84.8024193 217.767888,90.3805017 221.54,98.58 C223.424615,101.689762 227.141337,103.174819 230.65,102.22 C236.02,101.07 235.65,106.15 243.76,107.87 L243.75,106.42 Z" id="Path" fill="#48C4E5"></path>
<path d="M261.46,105.38 L261.46,105.27 C261.34,73.03 235.17,45.45 202.91,45.45 C183.207085,45.4363165 164.821777,55.3450614 154,71.81 L153.79,71.45 L137.23,45.45 L97.5,45.4499858 L135.25,104.57 L98.41,162.57 L137,162.57 L153.79,136.78 L170.88,162.57 L209.48,162.57 L174.48,107.49 C173.899005,106.416838 173.583536,105.220114 173.56,104 C173.557346,96.2203871 176.64661,88.7586448 182.147627,83.2576275 C187.648645,77.7566101 195.110387,74.6673462 202.89,74.67 C219.11,74.67 221.82,84.37 225.32,88.93 C232.23,97.93 246.03,93.99 246.03,105.73 L246.03,105.73 C246.071086,108.480945 247.576662,111.001004 249.979593,112.340896 C252.382524,113.680787 255.317747,113.636949 257.679593,112.225896 C260.041438,110.814842 261.471086,108.250945 261.43,105.5 L261.43,105.5 L261.43,105.38 L261.46,105.38 Z" id="Path" fill="#FFFFFF"></path>
<path d="M261.5,113.68 C261.892278,116.421801 261.504116,119.218653 260.38,121.75 C258.18,126.84 254.51,125.14 254.51,125.14 C254.51,125.14 251.35,123.6 253.27,120.65 C255.4,117.36 259.61,117.74 261.5,113.68 Z" id="Path" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

@ -14,38 +14,35 @@ interface Props extends RouteProps {
from: string
}
const RouteWithHeader = ({ component: Component, ...rest }: Props) => {
return (
<Route
{...rest}
>
<DefaultLayout {...rest}>
<Component />
</DefaultLayout>
</Route>
)
}
export const DisplayRoutes = () => (
<Router>
<Routes>
<Route
path="/"
element={<DefaultLayout from="/" title="Verify Smart Contracts">
<HomeView />
</DefaultLayout>} />
element={
<DefaultLayout from="/" title="Verify Smart Contracts">
<HomeView />
</DefaultLayout>
}
/>
<Route path="/error"
element={<ErrorView />} />
<Route
path="/receipts"
element={<DefaultLayout from="/receipts" title="Check Receipt GUID Status">
<ReceiptsView />
</DefaultLayout>} />
element={
<DefaultLayout from="/receipts" title="Check Receipt GUID Status">
<ReceiptsView />
</DefaultLayout>
}
/>
<Route
path="/settings"
element={<DefaultLayout from="/settings" title="Set Explorer API Key">
<CaptureKeyView />
</DefaultLayout>} />
element={
<DefaultLayout from="/settings" title="Set Explorer API Key">
<CaptureKeyView />
</DefaultLayout>
}
/>
</Routes>
</Router>
)

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg
className="material-icons"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
>
<path d="M0 0h24v24H0z" fill="none" />
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" />
</svg>

Before

Width:  |  Height:  |  Size: 347 B

@ -5,203 +5,202 @@ import axios from 'axios'
import { PluginClient } from "@remixproject/plugin"
const resetAfter10Seconds = (client: PluginClient, setResults: (value: string) => void) => {
setTimeout(() => {
client.emit("statusChanged", { key: "none" })
setResults("")
}, 10000)
}
setTimeout(() => {
client.emit("statusChanged", { key: "none" })
setResults("")
}, 10000)
}
export type EtherScanReturn = {
guid: any,
status: any,
guid: any,
status: any,
}
export const verify = async (
apiKeyParam: string,
contractAddress: string,
contractArgumentsParam: string,
contractName: string,
compilationResultParam: CompilerAbstract,
chainRef: number | string,
isProxyContract: boolean,
expectedImplAddress: string,
client: PluginClient,
onVerifiedContract: (value: EtherScanReturn) => void,
setResults: (value: string) => void
) => {
let networkChainId
let etherscanApi
if (chainRef) {
if (typeof chainRef === 'number') {
networkChainId = chainRef
etherscanApi = getEtherScanApi(networkChainId)
} else if (typeof chainRef === 'string') etherscanApi = chainRef
apiKeyParam: string,
contractAddress: string,
contractArgumentsParam: string,
contractName: string,
compilationResultParam: CompilerAbstract,
chainRef: number | string,
isProxyContract: boolean,
expectedImplAddress: string,
client: PluginClient,
onVerifiedContract: (value: EtherScanReturn) => void,
setResults: (value: string) => void
) => {
let networkChainId
let etherscanApi
if (chainRef) {
if (typeof chainRef === 'number') {
networkChainId = chainRef
etherscanApi = getEtherScanApi(networkChainId)
} else if (typeof chainRef === 'string') etherscanApi = chainRef
} else {
const { network, networkId } = await getNetworkName(client)
if (network === "vm") {
return {
succeed: false,
message: "Cannot verify in the selected network"
}
} else {
const { network, networkId } = await getNetworkName(client)
if (network === "vm") {
return {
succeed: false,
message: "Cannot verify in the selected network"
}
} else {
networkChainId = networkId
etherscanApi = getEtherScanApi(networkChainId)
networkChainId = networkId
etherscanApi = getEtherScanApi(networkChainId)
}
}
try {
const contractMetadata = getContractMetadata(
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository
compilationResultParam.data as unknown as CompilationResult,
contractName
)
if (!contractMetadata) {
return {
succeed: false,
message: "Please recompile contract"
}
}
const contractMetadataParsed = JSON.parse(contractMetadata)
try {
const contractMetadata = getContractMetadata(
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository
compilationResultParam.data as unknown as CompilationResult,
contractName
)
const fileName = getContractFileName(
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository
compilationResultParam.data as unknown as CompilationResult,
contractName
)
if (!contractMetadata) {
return {
succeed: false,
message: "Please recompile contract"
const jsonInput = {
language: 'Solidity',
sources: compilationResultParam.source.sources,
settings: {
optimizer: {
enabled: contractMetadataParsed.settings.optimizer.enabled,
runs: contractMetadataParsed.settings.optimizer.runs
}
}
const contractMetadataParsed = JSON.parse(contractMetadata)
const fileName = getContractFileName(
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository
compilationResultParam.data as unknown as CompilationResult,
contractName
)
}
const jsonInput = {
language: 'Solidity',
sources: compilationResultParam.source.sources,
settings: {
optimizer: {
enabled: contractMetadataParsed.settings.optimizer.enabled,
runs: contractMetadataParsed.settings.optimizer.runs
}
}
}
const data: { [key: string]: string | any } = {
apikey: apiKeyParam, // A valid API-Key is required
module: "contract", // Do not change
action: "verifysourcecode", // Do not change
codeformat: "solidity-standard-json-input",
sourceCode: JSON.stringify(jsonInput),
contractname: fileName + ':' + contractName,
compilerversion: `v${contractMetadataParsed.compiler.version}`, // see http://etherscan.io/solcversions for list of support versions
constructorArguements: contractArgumentsParam ? contractArgumentsParam.replace('0x', '') : '', // if applicable
}
const data: { [key: string]: string | any } = {
apikey: apiKeyParam, // A valid API-Key is required
module: "contract", // Do not change
action: "verifysourcecode", // Do not change
codeformat: "solidity-standard-json-input",
sourceCode: JSON.stringify(jsonInput),
contractname: fileName + ':' + contractName,
compilerversion: `v${contractMetadataParsed.compiler.version}`, // see http://etherscan.io/solcversions for list of support versions
constructorArguements: contractArgumentsParam ? contractArgumentsParam.replace('0x', '') : '', // if applicable
}
if (isProxyContract) {
data.action = "verifyproxycontract"
data.expectedimplementation = expectedImplAddress
data.address = contractAddress
} else {
data.contractaddress = contractAddress
}
if (isProxyContract) {
data.action = "verifyproxycontract"
data.expectedimplementation = expectedImplAddress
data.address = contractAddress
} else {
data.contractaddress = contractAddress
}
const body = new FormData()
Object.keys(data).forEach((key) => body.append(key, data[key]))
const body = new FormData()
Object.keys(data).forEach((key) => body.append(key, data[key]))
client.emit("statusChanged", {
key: "loading",
type: "info",
title: "Verifying ...",
})
const response = await axios.post(etherscanApi, body)
const { message, result, status } = await response.data
client.emit("statusChanged", {
key: "loading",
type: "info",
title: "Verifying ...",
})
const response = await axios.post(etherscanApi, body)
const { message, result, status } = await response.data
if (message === "OK" && status === "1") {
resetAfter10Seconds(client, setResults)
let receiptStatus
if (isProxyContract) {
receiptStatus = await getProxyContractReceiptStatus(
result,
apiKeyParam,
etherscanApi
)
if (receiptStatus.status === '1') {
receiptStatus.message = receiptStatus.result
receiptStatus.result = 'Successfully Updated'
}
} else receiptStatus = await getReceiptStatus(
if (message === "OK" && status === "1") {
resetAfter10Seconds(client, setResults)
let receiptStatus
if (isProxyContract) {
receiptStatus = await getProxyContractReceiptStatus(
result,
apiKeyParam,
etherscanApi
)
const returnValue = {
guid: result,
status: receiptStatus.result,
message: `Verification process started correctly. Receipt GUID ${result}`,
succeed: true,
isProxyContract
if (receiptStatus.status === '1') {
receiptStatus.message = receiptStatus.result
receiptStatus.result = 'Successfully Updated'
}
onVerifiedContract(returnValue)
return returnValue
} else if (message === "NOTOK") {
client.emit("statusChanged", {
key: "failed",
type: "error",
title: result,
})
const returnValue = {
message: result,
succeed: false,
isProxyContract
}
resetAfter10Seconds(client, setResults)
return returnValue
}
return {
message: 'unknown reason ' + result,
succeed: false
} else receiptStatus = await getReceiptStatus(
result,
apiKeyParam,
etherscanApi
)
const returnValue = {
guid: result,
status: receiptStatus.result,
message: `Verification process started correctly. Receipt GUID ${result}`,
succeed: true,
isProxyContract
}
} catch (error: any) {
console.error(error)
setResults("Something wrong happened, try again")
return {
message: error.message,
succeed: false
onVerifiedContract(returnValue)
return returnValue
} else if (message === "NOTOK") {
client.emit("statusChanged", {
key: "failed",
type: "error",
title: result,
})
const returnValue = {
message: result,
succeed: false,
isProxyContract
}
resetAfter10Seconds(client, setResults)
return returnValue
}
return {
message: 'unknown reason ' + result,
succeed: false
}
} catch (error: any) {
console.error(error)
setResults("Something wrong happened, try again")
return {
message: error.message,
succeed: false
}
}
}
export const getContractFileName = (
compilationResult: CompilationResult,
contractName: string
) => {
const compiledContracts = compilationResult.contracts
let fileName = ""
for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) {
fileName = file
break
}
export const getContractFileName = (
compilationResult: CompilationResult,
contractName: string
) => {
const compiledContracts = compilationResult.contracts
let fileName = ""
for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) {
fileName = file
break
}
}
return fileName
}
return fileName
}
export const getContractMetadata = (
compilationResult: CompilationResult,
contractName: string
) => {
const compiledContracts = compilationResult.contracts
let contractMetadata = ""
for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) {
contractMetadata = compiledContracts[file][contract].metadata
if (contractMetadata) {
break
}
export const getContractMetadata = (
compilationResult: CompilationResult,
contractName: string
) => {
const compiledContracts = compilationResult.contracts
let contractMetadata = ""
for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) {
contractMetadata = compiledContracts[file][contract].metadata
if (contractMetadata) {
break
}
}
}
return contractMetadata
}
return contractMetadata
}

@ -37,7 +37,7 @@ export const CaptureKeyView: React.FC = () => {
>
{({ errors, touched, handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div className="form-group" style={{ marginBottom: "0.5rem" }}>
<div className="form-group mb-2">
<label htmlFor="apikey">API Key</label>
<Field
className={
@ -62,8 +62,7 @@ export const CaptureKeyView: React.FC = () => {
</form>
)}
</Formik>
}
}
}}
</AppContext.Consumer>
)
}

@ -2,25 +2,18 @@ import React from "react"
export const ErrorView: React.FC = () => {
return (
<div
style={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<div className="d-flex w-100 flex-column align-items-center">
<img
style={{ paddingBottom: "2em" }}
className="pb-4"
width="250"
src="https://res.cloudinary.com/key-solutions/image/upload/v1580400635/solid/error-png.png"
alt="Error page"
/>
<h5>Sorry, something unexpected happened. </h5>
<h5>Sorry, something unexpected happened.</h5>
<h5>
Please raise an issue:{" "}
<a
style={{ color: "red" }}
className="text-danger"
href="https://github.com/ethereum/remix-project/issues"
>
Here

@ -8,7 +8,6 @@ import { Receipt } from "../types"
import { VerifyView } from "./VerifyView"
export const HomeView: React.FC = () => {
// const [hasError, setHasError] = useState(false)
return (
<AppContext.Consumer>
{({ apiKey, clientInstance, setReceipts, receipts, contracts }) => {

@ -92,10 +92,7 @@ export const ReceiptsView: React.FC = () => {
>
{({ errors, touched, handleSubmit, handleChange }) => (
<form onSubmit={handleSubmit}>
<div
className="form-group"
style={{ marginBottom: "0.5rem" }}
>
<div className="form-group mb-2">
<label htmlFor="receiptGuid">Receipt GUID</label>
<Field
className={
@ -114,31 +111,26 @@ export const ReceiptsView: React.FC = () => {
</div>
<div className="d-flex mb-2 custom-control custom-checkbox">
<Field
className="custom-control-input"
type="checkbox"
name="isProxyReceipt"
id="isProxyReceipt"
onChange={async (e) => {
handleChange(e)
if (e.target.checked) setIsProxyContractReceipt(true)
else setIsProxyContractReceipt(false)
}}
/>
<label className="form-check-label custom-control-label" htmlFor="isProxyReceipt">It's a proxy contract GUID</label>
</div>
<Field
className="custom-control-input"
type="checkbox"
name="isProxyReceipt"
id="isProxyReceipt"
onChange={async (e) => {
handleChange(e)
if (e.target.checked) setIsProxyContractReceipt(true)
else setIsProxyContractReceipt(false)
}}
/>
<label className="form-check-label custom-control-label" htmlFor="isProxyReceipt">It's a proxy contract GUID</label>
</div>
<SubmitButton text="Check" disable = {!touched.receiptGuid || (touched.receiptGuid && errors.receiptGuid) ? true : false} />
</form>
)}
</Formik>
<div
style={{
marginTop: "2em",
fontSize: "0.8em",
textAlign: "center",
color: results['succeed'] ? "green" : "red"
}}
className={results['succeed'] ? "text-success mt-3 text-center" : "text-danger mt-3 text-center"}
dangerouslySetInnerHTML={{ __html: results.message ? results.message : '' }}
/>
@ -148,7 +140,7 @@ export const ReceiptsView: React.FC = () => {
tooltipId='etherscan-clear-receipts'
placement='bottom'
>
<Button onClick={() => { setReceipts([]) }} >Clear</Button>
<Button className="btn-sm" onClick={() => { setReceipts([]) }} >Clear</Button>
</CustomTooltip>
</div>
)
@ -160,9 +152,9 @@ export const ReceiptsView: React.FC = () => {
const ReceiptsTable: React.FC<{ receipts: Receipt[] }> = ({ receipts }) => {
return (
<div className="table-responsive" style={{ fontSize: "0.8em" }}>
<div className="table-responsive">
<h6>Receipts</h6>
<table className="table table-sm">
<table className="table h6 table-sm">
<thead>
<tr>
<th scope="col">Status</th>

@ -132,15 +132,15 @@ export const VerifyView: React.FC<Props> = ({
}
name="contractName"
onChange={async (e) => {
handleChange(e)
const {artefact} = await client.call("compilerArtefacts" as any, "getArtefactsByContractName", e.target.value)
if (artefact && artefact.abi && artefact.abi[0] && artefact.abi[0].type && artefact.abi[0].type === 'constructor' && artefact.abi[0].inputs.length > 0) {
setConstructorInputs(artefact.abi[0].inputs)
setShowConstructorArgs(true)
} else {
setConstructorInputs([])
setShowConstructorArgs(false)
}
handleChange(e)
const {artefact} = await client.call("compilerArtefacts" as any, "getArtefactsByContractName", e.target.value)
if (artefact && artefact.abi && artefact.abi[0] && artefact.abi[0].type && artefact.abi[0].type === 'constructor' && artefact.abi[0].inputs.length > 0) {
setConstructorInputs(artefact.abi[0].inputs)
setShowConstructorArgs(true)
} else {
setConstructorInputs([])
setShowConstructorArgs(false)
}
}}
>
<option disabled={true} value="">
@ -260,8 +260,7 @@ export const VerifyView: React.FC<Props> = ({
>
<button
type="button"
style={{ padding: "0.25rem 0.4rem", marginRight: "0.5em", marginBottom: "0.5em"}}
className="btn btn-secondary btn-block"
className="mr-2 mb-2 py-1 px-2 btn btn-secondary btn-block"
onClick={async () => {
etherscanScripts(client)
}}
@ -275,8 +274,10 @@ export const VerifyView: React.FC<Props> = ({
}
</Formik>
<div data-id="verify-result"
style={{ marginTop: "2em", fontSize: "0.8em", textAlign: "center", color: verificationResult.current['succeed'] ? "green" : "red" }}
<div
data-id="verify-result"
className={verificationResult.current['succeed'] ? "text-success mt-4 text-center" : "text-danger mt-4 text-center"}
style={{fontSize: "0.8em"}}
dangerouslySetInnerHTML={{ __html: results }}
/>

@ -36,7 +36,7 @@ function RootView ({ pluginComponent, children }: RootViewProps) {
return (
<Fragment>
<div id="pluginManager" data-id="pluginManagerComponentPluginManager">
<header className="form-group remixui_pluginSearch plugins-header py-3 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader">
<header className="form-group remixui_pluginSearch plugins-header pt-3 pb-0 px-4 border-bottom" data-id="pluginManagerComponentPluginManagerHeader">
<input
type="text"
onChange={(event) => {

Loading…
Cancel
Save