Commit 1374ea80 authored by tom's avatar tom

Update verification methods in the UI

parent 07c2433f
import type { SmartContractVerificationMethodExtra } from 'types/client/contract';
import { SMART_CONTRACT_EXTRA_VERIFICATION_METHODS } from 'types/client/contract';
import type { AddressViewId, IdenticonType } from 'types/views/address';
import { ADDRESS_VIEWS_IDS, IDENTICON_TYPES } from 'types/views/address';
......@@ -24,10 +26,26 @@ const hiddenViews = (() => {
return result;
})();
const extraVerificationMethods: Array<SmartContractVerificationMethodExtra> = (() => {
const envValue = getEnvValue('NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS');
if (envValue === 'none') {
return [];
}
if (!envValue) {
return SMART_CONTRACT_EXTRA_VERIFICATION_METHODS;
}
const parsedMethods = parseEnvJson<Array<SmartContractVerificationMethodExtra>>(getEnvValue('NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS')) || [];
return SMART_CONTRACT_EXTRA_VERIFICATION_METHODS.filter((method) => parsedMethods.includes(method));
})();
const config = Object.freeze({
identiconType,
hiddenViews,
solidityscanEnabled: getEnvValue('NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED') === 'true',
extraVerificationMethods,
});
export default config;
/* eslint-disable max-len */
declare module 'yup' {
interface StringSchema {
// Yup's URL validator is not perfect so we made our own
......@@ -11,7 +12,7 @@ import * as yup from 'yup';
import type { AdButlerConfig } from '../../../types/client/adButlerConfig';
import { SUPPORTED_AD_TEXT_PROVIDERS, SUPPORTED_AD_BANNER_PROVIDERS, SUPPORTED_AD_BANNER_ADDITIONAL_PROVIDERS } from '../../../types/client/adProviders';
import type { AdTextProviders, AdBannerProviders, AdBannerAdditionalProviders } from '../../../types/client/adProviders';
import type { ContractCodeIde } from '../../../types/client/contract';
import { SMART_CONTRACT_EXTRA_VERIFICATION_METHODS, type ContractCodeIde, type SmartContractVerificationMethodExtra } from '../../../types/client/contract';
import type { DeFiDropdownItem } from '../../../types/client/deFiDropdown';
import type { GasRefuelProviderConfig } from '../../../types/client/gasRefuelProviderConfig';
import { GAS_UNITS } from '../../../types/client/gasTracker';
......@@ -576,6 +577,21 @@ const schema = yup
.json()
.of(yup.string<AddressViewId>().oneOf(ADDRESS_VIEWS_IDS)),
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED: yup.boolean(),
NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS: yup
.mixed()
.test(
'shape',
'Invalid schema were provided for NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS, it should be either array of method ids or "none" string literal',
(data) => {
const isNoneSchema = yup.string().oneOf([ 'none' ]);
const isArrayOfMethodsSchema = yup
.array()
.transform(replaceQuotes)
.json()
.of(yup.string<SmartContractVerificationMethodExtra>().oneOf(SMART_CONTRACT_EXTRA_VERIFICATION_METHODS));
return isNoneSchema.isValidSync(data) || isArrayOfMethodsSchema.isValidSync(data);
}),
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS: yup
.array()
.transform(replaceQuotes)
......
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=none
NEXT_PUBLIC_API_SPEC_URL=none
NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS=none
\ No newline at end of file
......@@ -68,6 +68,7 @@ NEXT_PUBLIC_STATS_API_BASE_PATH=/
NEXT_PUBLIC_USE_NEXT_JS_PROXY=false
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE=gradient_avatar
NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS=['top_accounts']
NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS=['solidity-hardhat','solidity-foundry']
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=['burnt_fees','total_reward']
NEXT_PUBLIC_VIEWS_NFT_MARKETPLACES=[{'name':'NFT Marketplace','collection_url':'https://example.com/{hash}','instance_url':'https://example.com/{hash}/{id}','logo_url':'https://example.com/logo.png'}]
NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS=['fee_per_gas']
......
......@@ -221,6 +221,7 @@ Settings for meta tags, OG tags and SEO
| NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE | `"github" \| "jazzicon" \| "gradient_avatar" \| "blockie"` | Default style of address identicon appearance. Choose between [GitHub](https://github.blog/2013-08-14-identicons/), [Metamask Jazzicon](https://metamask.github.io/jazzicon/), [Gradient Avatar](https://github.com/varld/gradient-avatar) and [Ethereum Blocky](https://mycryptohq.github.io/ethereum-blockies-base64/) | - | `jazzicon` | `gradient_avatar` | v1.12.0+ |
| NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS | `Array<AddressViewId>` | Address views that should not be displayed. See below the list of the possible id values. | - | - | `'["top_accounts"]'` | v1.15.0+ |
| NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED | `boolean` | Set to `true` if SolidityScan reports are supported | - | - | `true` | v1.19.0+ |
| NEXT_PUBLIC_VIEWS_CONTRACT_EXTRA_VERIFICATION_METHODS | `Array<'solidity-hardhat' \| 'solidity-foundry'>` | Pass an array of additional methods from which users can choose while verifying a smart contract. Both methods are available by default, pass `'none'` string to disable them all. | - | - | `['solidity-hardhat']` | v1.33.0+ |
##### Address views list
| Id | Description |
......
......@@ -54,7 +54,7 @@ import type { ChartMarketResponse, ChartSecondaryCoinPriceResponse, ChartTransac
import type { BackendVersionConfig } from 'types/api/configs';
import type {
SmartContract,
SmartContractVerificationConfig,
SmartContractVerificationConfigRaw,
SolidityscanReport,
SmartContractSecurityAudits,
} from 'types/api/contract';
......@@ -1028,7 +1028,7 @@ Q extends 'contract_solidityscan_report' ? SolidityscanReport :
Q extends 'verified_contracts' ? VerifiedContractsResponse :
Q extends 'verified_contracts_counters' ? VerifiedContractsCounters :
Q extends 'visualize_sol2uml' ? visualizer.VisualizeResponse :
Q extends 'contract_verification_config' ? SmartContractVerificationConfig :
Q extends 'contract_verification_config' ? SmartContractVerificationConfigRaw :
Q extends 'withdrawals' ? WithdrawalsResponse :
Q extends 'withdrawals_counters' ? WithdrawalsCounters :
Q extends 'optimistic_l2_output_roots' ? OptimisticL2OutputRootsResponse :
......
......@@ -75,7 +75,7 @@ export interface SmartContractExternalLibrary {
// VERIFICATION
export type SmartContractVerificationMethod = 'flattened-code' | 'standard-input' | 'sourcify' | 'multi-part'
export type SmartContractVerificationMethodApi = 'flattened-code' | 'standard-input' | 'sourcify' | 'multi-part'
| 'vyper-code' | 'vyper-multi-part' | 'vyper-standard-input';
export interface SmartContractVerificationConfigRaw {
......@@ -88,10 +88,6 @@ export interface SmartContractVerificationConfigRaw {
license_types: Record<SmartContractLicenseType, number>;
}
export interface SmartContractVerificationConfig extends SmartContractVerificationConfigRaw {
verification_options: Array<SmartContractVerificationMethod>;
}
export type SmartContractVerificationResponse = {
status: 'error';
errors: SmartContractVerificationError;
......
import type { SmartContractLicenseType } from 'types/api/contract';
import type { SmartContractLicenseType, SmartContractVerificationConfigRaw, SmartContractVerificationMethodApi } from 'types/api/contract';
export interface ContractCodeIde {
title: string;
......@@ -12,3 +12,16 @@ export interface ContractLicense {
label: string;
title: string;
}
export const SMART_CONTRACT_EXTRA_VERIFICATION_METHODS = [
'solidity-hardhat' as const,
'solidity-foundry' as const,
];
export type SmartContractVerificationMethodExtra = (typeof SMART_CONTRACT_EXTRA_VERIFICATION_METHODS)[number];
export type SmartContractVerificationMethod = SmartContractVerificationMethodApi | SmartContractVerificationMethodExtra;
export interface SmartContractVerificationConfig extends SmartContractVerificationConfigRaw {
verification_options: Array<SmartContractVerificationMethod>;
}
import React from 'react';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import * as socketServer from 'playwright/fixtures/socketServer';
import { test, expect } from 'playwright/lib';
......@@ -37,6 +37,8 @@ const formConfig: SmartContractVerificationConfig = {
'vyper-code',
'vyper-multi-part',
'vyper-standard-input',
'solidity-hardhat',
'solidity-foundry',
],
vyper_compiler_versions: [
'v0.3.7+commit.6020b8bb',
......@@ -82,7 +84,7 @@ test('flatten source code method +@dark-mode +@mobile', async({ render, page })
// select method
await component.getByLabel(/verification method/i).focus();
await component.getByLabel(/verification method/i).fill('solidity');
await page.getByRole('button', { name: /flattened source code/i }).click();
await page.getByRole('button', { name: /single file/i }).click();
await page.getByText(/add contract libraries/i).click();
await page.locator('button[aria-label="add"]').click();
......@@ -191,3 +193,25 @@ test('vyper vyper-standard-input method', async({ render, page }) => {
await expect(component).toHaveScreenshot();
});
test('solidity-hardhat method', async({ render, page }) => {
const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
// select method
await component.getByLabel(/verification method/i).focus();
await component.getByLabel(/verification method/i).fill('hardhat');
await page.getByRole('button', { name: /hardhat/i }).click();
await expect(component).toHaveScreenshot();
});
test('solidity-foundry method', async({ render, page }) => {
const component = await render(<ContractVerificationForm config={ formConfig } hash={ hash }/>, { hooksConfig });
// select method
await component.getByLabel(/verification method/i).focus();
await component.getByLabel(/verification method/i).fill('foundry');
await page.getByRole('button', { name: /foundry/i }).click();
await expect(component).toHaveScreenshot();
});
......@@ -5,7 +5,8 @@ import { useForm, FormProvider } from 'react-hook-form';
import type { FormFields } from './types';
import type { SocketMessage } from 'lib/socket/types';
import type { SmartContractVerificationMethod, SmartContractVerificationConfig, SmartContract } from 'types/api/contract';
import type { SmartContract, SmartContractVerificationMethodApi } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import { route } from 'nextjs-routes';
......@@ -22,6 +23,8 @@ import ContractVerificationFieldLicenseType from './fields/ContractVerificationF
import ContractVerificationFieldMethod from './fields/ContractVerificationFieldMethod';
import ContractVerificationFlattenSourceCode from './methods/ContractVerificationFlattenSourceCode';
import ContractVerificationMultiPartFile from './methods/ContractVerificationMultiPartFile';
import ContractVerificationSolidityFoundry from './methods/ContractVerificationSolidityFoundry';
import ContractVerificationSolidityHardhat from './methods/ContractVerificationSolidityHardhat';
import ContractVerificationSourcify from './methods/ContractVerificationSourcify';
import ContractVerificationStandardInput from './methods/ContractVerificationStandardInput';
import ContractVerificationVyperContract from './methods/ContractVerificationVyperContract';
......@@ -30,7 +33,7 @@ import ContractVerificationVyperStandardInput from './methods/ContractVerificati
import { prepareRequestBody, formatSocketErrors, getDefaultValues, METHOD_LABELS } from './utils';
interface Props {
method?: SmartContractVerificationMethod;
method?: SmartContractVerificationMethodApi;
config: SmartContractVerificationConfig;
hash?: string;
}
......@@ -159,6 +162,8 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
'vyper-code': <ContractVerificationVyperContract config={ config }/>,
'vyper-multi-part': <ContractVerificationVyperMultiPartFile/>,
'vyper-standard-input': <ContractVerificationVyperStandardInput/>,
'solidity-hardhat': <ContractVerificationSolidityHardhat config={ config }/>,
'solidity-foundry': <ContractVerificationSolidityFoundry/>,
};
}, [ config ]);
const method = watch('method');
......@@ -193,7 +198,7 @@ const ContractVerificationForm = ({ method: methodFromQuery, config, hash }: Pro
/>
</Grid>
{ content }
{ Boolean(method) && (
{ Boolean(method) && method.value !== 'solidity-hardhat' && method.value !== 'solidity-foundry' && (
<Button
variant="solid"
size="lg"
......
import { Code } from '@chakra-ui/react';
import React from 'react';
interface Props {
code: string;
}
const ContractVerificationFormCodeSnippet = ({ code }: Props) => {
return (
<Code whiteSpace="pre-wrap" wordBreak="break-all" p={ 2 } borderRadius="base">
{ code }
</Code>
);
};
export default React.memo(ContractVerificationFormCodeSnippet);
import { FormControl, Link, Textarea } from '@chakra-ui/react';
import { FormControl, Textarea } from '@chakra-ui/react';
import React from 'react';
import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
......@@ -43,12 +43,7 @@ const ContractVerificationFieldCode = ({ isVyper }: Props) => {
rules={{ required: true }}
/>
{ isVyper ? null : (
<>
<span>We recommend using flattened code. This is necessary if your code utilizes a library or inherits dependencies. Use the </span>
<Link href="https://hardhat.org/hardhat-runner/docs/advanced/flattening" target="_blank">Hardhat flattener</Link>
<span> or the </span>
<Link href="https://www.npmjs.com/package/truffle-flattener" target="_blank">Truffle flattener</Link>
</>
<span>If your code utilizes a library or inherits dependencies, we recommend using other verification methods instead.</span>
) }
</ContractVerificationFormRow>
);
......
......@@ -5,7 +5,7 @@ import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import { getResourceKey } from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
......
......@@ -5,7 +5,7 @@ import type { ControllerRenderProps } from 'react-hook-form';
import { useFormContext, Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import { getResourceKey } from 'lib/api/useApiQuery';
import useIsMobile from 'lib/hooks/useIsMobile';
......
......@@ -17,7 +17,7 @@ import type { ControllerRenderProps, Control } from 'react-hook-form';
import { Controller } from 'react-hook-form';
import type { FormFields } from '../types';
import type { SmartContractVerificationConfig, SmartContractVerificationMethod } from 'types/api/contract';
import type { SmartContractVerificationMethod, SmartContractVerificationConfig } from 'types/client/contract';
import useIsMobile from 'lib/hooks/useIsMobile';
import Popover from 'ui/shared/chakra/Popover';
......@@ -58,7 +58,7 @@ const ContractVerificationFieldMethod = ({ control, isDisabled, methods }: Props
const renderPopoverListItem = React.useCallback((method: SmartContractVerificationMethod) => {
switch (method) {
case 'flattened-code':
return <ListItem key={ method }>Verification through flattened source code.</ListItem>;
return <ListItem key={ method }>Verification through a single file.</ListItem>;
case 'multi-part':
return <ListItem key={ method }>Verification of multi-part Solidity files.</ListItem>;
case 'sourcify':
......@@ -93,6 +93,10 @@ const ContractVerificationFieldMethod = ({ control, isDisabled, methods }: Props
<span> file.</span>
</ListItem>
);
case 'solidity-hardhat':
return <ListItem key={ method }>Verification through Hardhat plugin.</ListItem>;
case 'solidity-foundry':
return <ListItem key={ method }>Verification through Foundry.</ListItem>;
}
}, []);
......
import React from 'react';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldAutodetectArgs from '../fields/ContractVerificationFieldAutodetectArgs';
......
import { Box, Flex, Link } from '@chakra-ui/react';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
import config from 'configs/app';
import ContractVerificationFormCodeSnippet from '../ContractVerificationFormCodeSnippet';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
import ContractVerificationMethod from '../ContractVerificationMethod';
const ContractVerificationSolidityFoundry = () => {
const { watch } = useFormContext<FormFields>();
const address = watch('address');
const codeSnippet = `forge verify-contract \\
--rpc-url ${ config.chain.rpcUrl || `${ config.api.endpoint }/api/eth-rpc` } \\
${ address || '<address>' } \\
[contractFile]:[contractName] \\
--verifier blockscout \\
--verifier-url '${ config.api.endpoint }/api/'`;
return (
<ContractVerificationMethod title="Contract verification via Foundry">
<ContractVerificationFormRow>
<Flex flexDir="column">
<ContractVerificationFormCodeSnippet code={ codeSnippet }/>
</Flex>
<Box whiteSpace="pre-wrap">
<span>Full tutorial about contract verification via Foundry on Blockscout is available </span>
<Link href="https://docs.blockscout.com/for-users/verifying-a-smart-contract/foundry-verification" target="_blank">
here
</Link>
</Box>
</ContractVerificationFormRow>
</ContractVerificationMethod>
);
};
export default React.memo(ContractVerificationSolidityFoundry);
import { Box, Flex, Link } from '@chakra-ui/react';
import React from 'react';
import { useFormContext } from 'react-hook-form';
import type { FormFields } from '../types';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import config from 'configs/app';
import ContractVerificationFormCodeSnippet from '../ContractVerificationFormCodeSnippet';
import ContractVerificationFormRow from '../ContractVerificationFormRow';
import ContractVerificationMethod from '../ContractVerificationMethod';
const ContractVerificationSolidityHardhat = ({ config: formConfig }: { config: SmartContractVerificationConfig }) => {
const chainNameSlug = config.chain.name?.toLowerCase().split(' ').join('-');
const { watch } = useFormContext<FormFields>();
const address = watch('address');
const latestSolidityVersion = formConfig.solidity_compiler_versions.find((version) => !version.includes('nightly'))?.split('+')[0];
const firstCodeSnippet = `const config: HardhatUserConfig = {
solidity: "${ latestSolidityVersion || '0.8.24' }", // replace if necessary
networks: {
'${ chainNameSlug }': {
url: '${ config.chain.rpcUrl || `${ config.api.endpoint }/api/eth-rpc` }'
},
},
etherscan: {
apiKey: {
'${ chainNameSlug }': 'empty'
},
customChains: [
{
network: "${ chainNameSlug }",
chainId: ${ config.chain.id },
urls: {
apiURL: "${ config.api.endpoint }/api",
browserURL: "${ config.app.baseUrl }"
}
}
]
}
};`;
const secondCodeSnippet = `npx hardhat verify \\
--network ${ chainNameSlug } \\
${ address || '<address>' } \\
[...constructorArgs]`;
return (
<ContractVerificationMethod title="Contract verification via Solidity Hardhat plugin">
<ContractVerificationFormRow>
<Flex flexDir="column" rowGap={ 3 }>
<ContractVerificationFormCodeSnippet code={ firstCodeSnippet }/>
<ContractVerificationFormCodeSnippet code={ secondCodeSnippet }/>
</Flex>
<Box whiteSpace="pre-wrap">
<span>Full tutorial about contract verification via Hardhat on Blockscout is available </span>
<Link href="https://docs.blockscout.com/for-users/verifying-a-smart-contract/hardhat-verification-plugin" target="_blank">
here
</Link>
</Box>
</ContractVerificationFormRow>
</ContractVerificationMethod>
);
};
export default React.memo(ContractVerificationSolidityHardhat);
import React from 'react';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldAutodetectArgs from '../fields/ContractVerificationFieldAutodetectArgs';
......
import React from 'react';
import type { SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContractVerificationConfig } from 'types/client/contract';
import ContractVerificationMethod from '../ContractVerificationMethod';
import ContractVerificationFieldCode from '../fields/ContractVerificationFieldCode';
......
import type { SmartContractLicenseType, SmartContractVerificationMethod } from 'types/api/contract';
import type { SmartContractLicenseType } from 'types/api/contract';
import type { SmartContractVerificationMethod } from 'types/client/contract';
import type { Option } from 'ui/shared/FancySelect/types';
export interface ContractLibrary {
......
import config from 'configs/app';
import useApiQuery from 'lib/api/useApiQuery';
import { isValidVerificationMethod, sortVerificationMethods } from './utils';
......@@ -8,7 +9,10 @@ export default function useFormConfigQuery(enabled: boolean) {
select: (data) => {
return {
...data,
verification_options: data.verification_options.filter(isValidVerificationMethod).sort(sortVerificationMethods),
verification_options: [
...data.verification_options,
...config.UI.views.address.extraVerificationMethods,
].filter(isValidVerificationMethod).sort(sortVerificationMethods),
};
},
enabled,
......
......@@ -12,11 +12,10 @@ import type {
FormFieldsVyperStandardInput,
} from './types';
import type {
SmartContractVerificationMethod,
SmartContractVerificationError,
SmartContractVerificationConfig,
SmartContractLicenseType,
} from 'types/api/contract';
import type { SmartContractVerificationConfig, SmartContractVerificationMethod } from 'types/client/contract';
import type { Params as FetchParams } from 'lib/hooks/useFetch';
......@@ -25,19 +24,23 @@ export const SUPPORTED_VERIFICATION_METHODS: Array<SmartContractVerificationMeth
'standard-input',
'sourcify',
'multi-part',
'solidity-hardhat',
'solidity-foundry',
'vyper-code',
'vyper-multi-part',
'vyper-standard-input',
];
export const METHOD_LABELS: Record<SmartContractVerificationMethod, string> = {
'flattened-code': 'Solidity (Flattened source code)',
'flattened-code': 'Solidity (Single file)',
'standard-input': 'Solidity (Standard JSON input)',
sourcify: 'Solidity (Sourcify)',
'multi-part': 'Solidity (Multi-part files)',
'vyper-code': 'Vyper (Contract)',
'vyper-multi-part': 'Vyper (Multi-part files)',
'vyper-standard-input': 'Vyper (Standard JSON input)',
'solidity-hardhat': 'Solidity (Hardhat)',
'solidity-foundry': 'Solidity (Foundry)',
};
export const DEFAULT_VALUES: Record<SmartContractVerificationMethod, FormFields> = {
......@@ -129,6 +132,26 @@ export const DEFAULT_VALUES: Record<SmartContractVerificationMethod, FormFields>
sources: [],
license_type: null,
},
'solidity-hardhat': {
address: '',
method: {
value: 'solidity-hardhat' as const,
label: METHOD_LABELS['solidity-hardhat'],
},
compiler: null,
sources: [],
license_type: null,
},
'solidity-foundry': {
address: '',
method: {
value: 'solidity-foundry' as const,
label: METHOD_LABELS['solidity-foundry'],
},
compiler: null,
sources: [],
license_type: null,
},
};
export function getDefaultValues(
......
import { useRouter } from 'next/router';
import React from 'react';
import type { SmartContractVerificationMethod } from 'types/api/contract';
import type { SmartContractVerificationMethodApi } from 'types/api/contract';
import type { SmartContractVerificationMethod } from 'types/client/contract';
import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/contexts/app';
......@@ -59,7 +60,7 @@ const ContractVerificationForAddress = () => {
return (
<ContractVerificationForm
method={ method && configQuery.data.verification_options.includes(method) ? method : undefined }
method={ method && configQuery.data.verification_options.includes(method) ? method as SmartContractVerificationMethodApi : undefined }
config={ configQuery.data }
hash={ hash }
/>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment