import { Flex, Select, Skeleton, Text, Tooltip } from '@chakra-ui/react'; import React from 'react'; import type { AddressImplementation } from 'types/api/addressParams'; import type { SmartContract } from 'types/api/contract'; import { route } from 'nextjs-routes'; import useApiQuery from 'lib/api/useApiQuery'; import * as stubs from 'stubs/contract'; import CopyToClipboard from 'ui/shared/CopyToClipboard'; import LinkInternal from 'ui/shared/links/LinkInternal'; import CodeEditor from 'ui/shared/monaco/CodeEditor'; import formatFilePath from 'ui/shared/monaco/utils/formatFilePath'; import ContractCodeIdes from './ContractCodeIdes'; import ContractExternalLibraries from './ContractExternalLibraries'; function getEditorData(contractInfo: SmartContract | undefined) { if (!contractInfo || !contractInfo.source_code) { return undefined; } const extension = (() => { switch (contractInfo.language) { case 'vyper': return 'vy'; case 'yul': return 'yul'; default: return 'sol'; } })(); return [ { file_path: formatFilePath(contractInfo.file_path || `index.${ extension }`), source_code: contractInfo.source_code }, ...(contractInfo.additional_sources || []).map((source) => ({ ...source, file_path: formatFilePath(source.file_path) })), ]; } interface SourceContractOption { address: string; label: string; } interface Props { address: string; implementations?: Array; } export const ContractSourceCode = ({ address, implementations }: Props) => { const options: Array = React.useMemo(() => { return [ { label: 'Proxy', address }, ...(implementations || []) .filter((item) => item.name && item.address !== address) .map(({ name, address }, item, array) => ({ address, label: array.length === 1 ? 'Implementation' : `Impl: ${ name }` })), ]; }, [ address, implementations ]); const [ sourceContract, setSourceContract ] = React.useState(options[0]); const contractQuery = useApiQuery('contract', { pathParams: { hash: sourceContract.address }, queryOptions: { refetchOnMount: false, placeholderData: stubs.CONTRACT_CODE_VERIFIED, }, }); const editorData = React.useMemo(() => { return getEditorData(contractQuery.data); }, [ contractQuery.data ]); const isLoading = contractQuery.isPlaceholderData; const handleSelectChange = React.useCallback((event: React.ChangeEvent) => { const nextOption = options.find(({ address }) => address === event.target.value); if (nextOption) { setSourceContract(nextOption); } }, [ options ]); const heading = ( Contract source code { contractQuery.data?.language && ({ contractQuery.data.language }) } ); const select = options.length > 1 ? ( ) : null; const externalLibraries = contractQuery.data?.external_libraries ? : null; const diagramLink = contractQuery?.data?.can_be_visualized_via_sol2uml ? ( View UML diagram ) : null; const ides = ; const copyToClipboard = contractQuery.data && editorData?.length === 1 ? ( ) : null; const content = (() => { if (isLoading) { return ; } if (!editorData) { return null; } return ( ); })(); return (
{ heading } { select } { externalLibraries } { diagramLink } { ides } { copyToClipboard } { content }
); }; export default React.memo(ContractSourceCode);