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

@ -15,33 +15,34 @@ export const SubmitButton: React.FC<Props> = ({
disable = true disable = true
}) => { }) => {
return ( return (
<CustomTooltip <div>
tooltipText={disable ? "Fill the fields with valid values" : "Click to proceed"} <button
tooltipId='etherscan-submit-button' data-id={dataId}
placement='bottom' type="submit"
> className="btn btn-primary btn-block p-1 text-decoration-none"
<div> disabled={disable}
<button >
data-id={dataId} <CustomTooltip
style={{ padding: "0.25rem 0.4rem", marginRight: "0.5em" }} tooltipText={disable ? "Fill the fields with valid values" : "Click to proceed"}
type="submit" tooltipId={'etherscan-submit-button-'+ dataId}
className="btn btn-primary btn-block text-decoration-none" tooltipTextClasses="border bg-light text-dark p-1 pr-3"
disabled={disable} placement='bottom'
> >
{!isSubmitting && text} <div>
{isSubmitting && ( {!isSubmitting && text}
<div> {isSubmitting && (
<span <div>
className="spinner-border spinner-border-sm" <span
role="status" className="spinner-border spinner-border-sm mr-1"
aria-hidden="true" role="status"
style={{ marginRight: "0.3em" }} aria-hidden="true"
/> />
Verifying... Please wait Verifying... Please wait
</div> </div>
)} )}
</button> </div>
</div> </CustomTooltip>
</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 from: string
} }
const RouteWithHeader = ({ component: Component, ...rest }: Props) => {
return (
<Route
{...rest}
>
<DefaultLayout {...rest}>
<Component />
</DefaultLayout>
</Route>
)
}
export const DisplayRoutes = () => ( export const DisplayRoutes = () => (
<Router> <Router>
<Routes> <Routes>
<Route <Route
path="/" path="/"
element={<DefaultLayout from="/" title="Verify Smart Contracts"> element={
<HomeView /> <DefaultLayout from="/" title="Verify Smart Contracts">
</DefaultLayout>} /> <HomeView />
</DefaultLayout>
}
/>
<Route path="/error" <Route path="/error"
element={<ErrorView />} /> element={<ErrorView />} />
<Route <Route
path="/receipts" path="/receipts"
element={<DefaultLayout from="/receipts" title="Check Receipt GUID Status"> element={
<ReceiptsView /> <DefaultLayout from="/receipts" title="Check Receipt GUID Status">
</DefaultLayout>} /> <ReceiptsView />
</DefaultLayout>
}
/>
<Route <Route
path="/settings" path="/settings"
element={<DefaultLayout from="/settings" title="Set Explorer API Key"> element={
<CaptureKeyView /> <DefaultLayout from="/settings" title="Set Explorer API Key">
</DefaultLayout>} /> <CaptureKeyView />
</DefaultLayout>
}
/>
</Routes> </Routes>
</Router> </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" import { PluginClient } from "@remixproject/plugin"
const resetAfter10Seconds = (client: PluginClient, setResults: (value: string) => void) => { const resetAfter10Seconds = (client: PluginClient, setResults: (value: string) => void) => {
setTimeout(() => { setTimeout(() => {
client.emit("statusChanged", { key: "none" }) client.emit("statusChanged", { key: "none" })
setResults("") setResults("")
}, 10000) }, 10000)
} }
export type EtherScanReturn = { export type EtherScanReturn = {
guid: any, guid: any,
status: any, status: any,
} }
export const verify = async ( export const verify = async (
apiKeyParam: string, apiKeyParam: string,
contractAddress: string, contractAddress: string,
contractArgumentsParam: string, contractArgumentsParam: string,
contractName: string, contractName: string,
compilationResultParam: CompilerAbstract, compilationResultParam: CompilerAbstract,
chainRef: number | string, chainRef: number | string,
isProxyContract: boolean, isProxyContract: boolean,
expectedImplAddress: string, expectedImplAddress: string,
client: PluginClient, client: PluginClient,
onVerifiedContract: (value: EtherScanReturn) => void, onVerifiedContract: (value: EtherScanReturn) => void,
setResults: (value: string) => void setResults: (value: string) => void
) => { ) => {
let networkChainId let networkChainId
let etherscanApi let etherscanApi
if (chainRef) { if (chainRef) {
if (typeof chainRef === 'number') { if (typeof chainRef === 'number') {
networkChainId = chainRef networkChainId = chainRef
etherscanApi = getEtherScanApi(networkChainId) etherscanApi = getEtherScanApi(networkChainId)
} else if (typeof chainRef === 'string') etherscanApi = chainRef } else if (typeof chainRef === 'string') etherscanApi = chainRef
} else { } else {
const { network, networkId } = await getNetworkName(client) const { network, networkId } = await getNetworkName(client)
if (network === "vm") { if (network === "vm") {
return { return {
succeed: false, succeed: false,
message: "Cannot verify in the selected network" message: "Cannot verify in the selected network"
}
} else {
networkChainId = networkId
etherscanApi = getEtherScanApi(networkChainId)
} }
} else {
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
)
try { if (!contractMetadata) {
const contractMetadata = getContractMetadata( return {
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository succeed: false,
compilationResultParam.data as unknown as CompilationResult, message: "Please recompile contract"
contractName }
) }
if (!contractMetadata) { const contractMetadataParsed = JSON.parse(contractMetadata)
return {
succeed: false, const fileName = getContractFileName(
message: "Please recompile contract" // 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 contractMetadataParsed = JSON.parse(contractMetadata) 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 fileName = getContractFileName( if (isProxyContract) {
// cast from the remix-plugin interface to the solidity one. Should be fixed when remix-plugin move to the remix-project repository data.action = "verifyproxycontract"
compilationResultParam.data as unknown as CompilationResult, data.expectedimplementation = expectedImplAddress
contractName data.address = contractAddress
) } else {
data.contractaddress = contractAddress
}
const jsonInput = { const body = new FormData()
language: 'Solidity', Object.keys(data).forEach((key) => body.append(key, data[key]))
sources: compilationResultParam.source.sources,
settings: {
optimizer: {
enabled: contractMetadataParsed.settings.optimizer.enabled,
runs: contractMetadataParsed.settings.optimizer.runs
}
}
}
const data: { [key: string]: string | any } = { client.emit("statusChanged", {
apikey: apiKeyParam, // A valid API-Key is required key: "loading",
module: "contract", // Do not change type: "info",
action: "verifysourcecode", // Do not change title: "Verifying ...",
codeformat: "solidity-standard-json-input", })
sourceCode: JSON.stringify(jsonInput), const response = await axios.post(etherscanApi, body)
contractname: fileName + ':' + contractName, const { message, result, status } = await response.data
compilerversion: `v${contractMetadataParsed.compiler.version}`, // see http://etherscan.io/solcversions for list of support versions
constructorArguements: contractArgumentsParam ? contractArgumentsParam.replace('0x', '') : '', // if applicable
}
if (message === "OK" && status === "1") {
resetAfter10Seconds(client, setResults)
let receiptStatus
if (isProxyContract) { if (isProxyContract) {
data.action = "verifyproxycontract" receiptStatus = await getProxyContractReceiptStatus(
data.expectedimplementation = expectedImplAddress
data.address = contractAddress
} else {
data.contractaddress = contractAddress
}
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
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(
result, result,
apiKeyParam, apiKeyParam,
etherscanApi etherscanApi
) )
if (receiptStatus.status === '1') {
const returnValue = { receiptStatus.message = receiptStatus.result
guid: result, receiptStatus.result = 'Successfully Updated'
status: receiptStatus.result,
message: `Verification process started correctly. Receipt GUID ${result}`,
succeed: true,
isProxyContract
}
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) } else receiptStatus = await getReceiptStatus(
return returnValue result,
} apiKeyParam,
return { etherscanApi
message: 'unknown reason ' + result, )
succeed: false
const returnValue = {
guid: result,
status: receiptStatus.result,
message: `Verification process started correctly. Receipt GUID ${result}`,
succeed: true,
isProxyContract
} }
} catch (error: any) { onVerifiedContract(returnValue)
console.error(error) return returnValue
setResults("Something wrong happened, try again") } else if (message === "NOTOK") {
return { client.emit("statusChanged", {
message: error.message, key: "failed",
succeed: false 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 = ( export const getContractFileName = (
compilationResult: CompilationResult, compilationResult: CompilationResult,
contractName: string contractName: string
) => { ) => {
const compiledContracts = compilationResult.contracts const compiledContracts = compilationResult.contracts
let fileName = "" let fileName = ""
for (const file of Object.keys(compiledContracts)) { for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) { for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) { if (contract === contractName) {
fileName = file fileName = file
break break
}
} }
} }
return fileName
} }
return fileName
}
export const getContractMetadata = ( export const getContractMetadata = (
compilationResult: CompilationResult, compilationResult: CompilationResult,
contractName: string contractName: string
) => { ) => {
const compiledContracts = compilationResult.contracts const compiledContracts = compilationResult.contracts
let contractMetadata = "" let contractMetadata = ""
for (const file of Object.keys(compiledContracts)) { for (const file of Object.keys(compiledContracts)) {
for (const contract of Object.keys(compiledContracts[file])) { for (const contract of Object.keys(compiledContracts[file])) {
if (contract === contractName) { if (contract === contractName) {
contractMetadata = compiledContracts[file][contract].metadata contractMetadata = compiledContracts[file][contract].metadata
if (contractMetadata) { if (contractMetadata) {
break break
}
} }
} }
} }
return contractMetadata
} }
return contractMetadata
}

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

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

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

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

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

@ -36,7 +36,7 @@ function RootView ({ pluginComponent, children }: RootViewProps) {
return ( return (
<Fragment> <Fragment>
<div id="pluginManager" data-id="pluginManagerComponentPluginManager"> <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 <input
type="text" type="text"
onChange={(event) => { onChange={(event) => {

Loading…
Cancel
Save