Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/616.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
For contracts, display bytecode
2 changes: 1 addition & 1 deletion src/app/components/Account/ShowMoreTokensLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { styled } from '@mui/material/styles'
import { COLORS } from '../../../styles/theme/colors'
import { EvmTokenType, RuntimeAccount, type Token } from '../../../oasis-indexer/api'
import { RouteUtils } from '../../utils/route-utils'
import { accountTokenContainerId } from '../../pages/AccountDetailsPage/TokensCard'
import { accountTokenContainerId } from '../../pages/AccountDetailsPage/AccountTokensCard'

export const StyledLink = styled(RouterLink)(({ theme }) => ({
color: COLORS.brandDark,
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { type RuntimeAccount } from '../../../oasis-indexer/api'
import { TokenPills } from './TokenPills'
import { AccountLink } from './AccountLink'
import { RouteUtils } from '../../utils/route-utils'
import { accountTransactionsContainerId } from '../../pages/AccountDetailsPage/TransactionsCard'
import { accountTransactionsContainerId } from '../../pages/AccountDetailsPage/AccountTransactionsCard'
import Link from '@mui/material/Link'
import { DashboardLink } from '../../pages/DashboardPage/DashboardLink'
import { getNameForTicker, Ticker } from '../../../types/ticker'
Expand Down
24 changes: 19 additions & 5 deletions src/app/components/CopyToClipboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy'
import { COLORS } from '../../../styles/theme/colors'
import ButtonBase from '@mui/material/ButtonBase'
import { styled } from '@mui/material/styles'
import Button from '@mui/material/Button'

const clipboardTooltipDuration = 2000

type CopyToClipboardProps = {
value: string
label?: string
}

const StyledButton = styled(ButtonBase)(({ theme }) => ({
const StyledIconButton = styled(ButtonBase)(({ theme }) => ({
display: 'inline-flex',
alignItems: 'center',
border: 0,
Expand All @@ -24,7 +26,7 @@ const StyledButton = styled(ButtonBase)(({ theme }) => ({
marginLeft: theme.spacing(4),
}))

export const CopyToClipboard: FC<CopyToClipboardProps> = ({ value }) => {
export const CopyToClipboard: FC<CopyToClipboardProps> = ({ value, label }) => {
const { t } = useTranslation()
const timeout = useRef<number | undefined>(undefined)
const ariaLabel = t('clipboard.label')
Expand All @@ -51,9 +53,21 @@ export const CopyToClipboard: FC<CopyToClipboardProps> = ({ value }) => {

return (
<Tooltip arrow onOpen={hideTooltip} open={isCopied} placement="right" title={t('clipboard.success')}>
<StyledButton color="inherit" onClick={handleCopyToClipboard} aria-label={ariaLabel}>
<ContentCopyIcon sx={{ fontSize: '1.25em', color: COLORS.brandDark }} />
</StyledButton>
{label ? (
<Button
variant="outlined"
color="secondary"
sx={{ textTransform: 'capitalize' }}
onClick={handleCopyToClipboard}
aria-label={ariaLabel}
>
{label}
</Button>
) : (
<StyledIconButton color="inherit" onClick={handleCopyToClipboard} aria-label={ariaLabel}>
<ContentCopyIcon sx={{ fontSize: '1.25em', color: COLORS.brandDark }} />
</StyledIconButton>
)}
</Tooltip>
)
}
7 changes: 1 addition & 6 deletions src/app/components/LongDataDisplay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,7 @@ export const LongDataDisplay: FC<{ data: string; threshold: number; fontWeight?:
}
return (
<div>
<Collapse
orientation={'vertical'}
in={showData}
onClick={() => setShowData(true)}
collapsedSize={'3em'}
>
<Collapse orientation="vertical" in={showData} onClick={() => setShowData(true)} collapsedSize="3em">
<Typography
variant="mono"
sx={{
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/ParaTimePicker/LayerMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const DisabledLayerMenuItem: FC<BaseLayerMenuItemProps> = ({ divider, lay
const labels = getLayerLabels(t)

return (
<Tooltip arrow placement="top" title={'Coming soon'}>
<Tooltip arrow placement="top" title="Coming soon">
Comment thread
csillag marked this conversation as resolved.
{/* Div is needed because we need an element with enabled pointer-events to make Tooltip work */}
<div>
<MenuItem disabled divider={divider}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('RoundedBalance', () => {

describe('RoundedRoseBalance', () => {
it('should render value with ROSE ticker symbol', () => {
render(<RoundedBalance value="0.002231" ticker={'ROSE'} />)
render(<RoundedBalance value="0.002231" ticker="ROSE" />)

expect(screen.getByText('0.00223… ROSE')).toBeInTheDocument()
})
Expand Down
44 changes: 44 additions & 0 deletions src/app/components/ScrollingDataDisplay/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { FC } from 'react'
import Typography from '@mui/material/Typography'
import Box from '@mui/material/Box'
import { COLORS } from '../../../styles/theme/colors'

export const ScrollingDataDisplay: FC<{ data: string; fontWeight?: number }> = ({
data,
fontWeight = 700,
}) => {
return (
<Box
sx={{
display: 'flex',
padding: '10px 0px 0px 0px',
flexDirection: 'column',
alignItems: 'flex-start',
gap: '10px',
}}
>
<Box
sx={{
borderRadius: '5px',
background: COLORS.grayLight,
border: `1px solid ${COLORS.grayMedium}`,
height: '349px',
overflowY: 'scroll',
p: 3,
}}
>
<Typography
Comment thread
csillag marked this conversation as resolved.
variant="mono"
fontSize={16}
sx={{
Comment thread
csillag marked this conversation as resolved.
fontWeight,
overflowWrap: 'anywhere',
}}
color={COLORS.grayMedium}
>
{data}
Comment thread
csillag marked this conversation as resolved.
</Typography>
</Box>
</Box>
)
}
2 changes: 1 addition & 1 deletion src/app/components/Select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const TertiaryButton = forwardRef(
const { t } = useTranslation()

return (
<StyledButton {...restProps} ref={ref} color={'tertiary'}>
<StyledButton {...restProps} ref={ref} color="tertiary">
<Typography variant="select">{children ? children : t('select.placeholder')}</Typography>
{ownerState.open ? <ExpandLessIcon /> : <ExpandMoreIcon />}
</StyledButton>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/TransactionStatusIcon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const statusFgColor: Record<TxStatus, string> = {
}

const statusIcon: Record<TxStatus, ReactNode> = {
unknown: <HelpIcon color={'inherit'} fontSize="inherit" />,
unknown: <HelpIcon color="inherit" fontSize="inherit" />,
success: <CheckCircleIcon color="success" fontSize="inherit" />,
failure: <CancelIcon color="error" fontSize="inherit" />,
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Transactions/LogEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export const TransactionLogEvent: FC<{

return (
<>
{!isFirst && <Divider variant={'card'} />}
{!isFirst && <Divider variant="card" />}
<StyledDescriptionList titleWidth={isMobile ? '100px' : '200px'}>
{decoded && (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ import { ScrollingDiv } from '../../components/PageLayout/ScrollingDiv'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { useAccount } from './hook'

type TokensCardProps = {
type AccountTokensCardProps = {
type: EvmTokenType
}

export const accountTokenContainerId = 'tokens'

export const TokensCard: FC<TokensCardProps> = ({ type }) => {
export const AccountTokensCard: FC<AccountTokensCardProps> = ({ type }) => {
const scope = useRequiredScopeParam()
const address = useLoaderData() as string
const { t } = useTranslation()
const locationHash = useLocation().hash.replace('#', '')
const tokenLabel = t(`account.${type}` as any)
const tokenListLabel = t('account.tokensListTitle', { token: tokenLabel })
const tokenListLabel = t('common.tokens') // TODO: re-enable when we want multiple token types again t('account.tokensListTitle', { token: tokenLabel })
const tableColumns: TableColProps[] = [
{ key: 'name', content: t('common.name') },
{ key: 'contract', content: t('common.smartContract') },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ import { NUMBER_OF_ITEMS_ON_SEPARATE_PAGE } from '../../config'
import { ErrorBoundary } from '../../components/ErrorBoundary'
import { ScrollingDiv } from '../../components/PageLayout/ScrollingDiv'
import { CardEmptyState } from './CardEmptyState'
import { useTransactions } from './hook'
import { useAccountTransactions } from './hook'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { useLoaderData } from 'react-router-dom'

export const accountTransactionsContainerId = 'transactions'

export const TransactionsCard: FC = () => {
export const AccountTransactionsCard: FC = () => {
const { t } = useTranslation()
const scope = useRequiredScopeParam()
const address = useLoaderData() as string

const { isLoading, isFetched, transactions, pagination, totalCount, isTotalCountClipped } = useTransactions(
scope,
address,
)
const { isLoading, isFetched, transactions, pagination, totalCount, isTotalCountClipped } =
useAccountTransactions(scope, address)
return (
<Card>
<ScrollingDiv id={accountTransactionsContainerId}>
Expand Down
75 changes: 75 additions & 0 deletions src/app/pages/AccountDetailsPage/ContractCodeCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Card from '@mui/material/Card'
import CardContent from '@mui/material/CardContent'
import { ScrollingDiv } from '../../components/PageLayout/ScrollingDiv'
import { useAccount } from './hook'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { useLoaderData } from 'react-router-dom'
import { CardEmptyState } from './CardEmptyState'
import Typography from '@mui/material/Typography'
import { ScrollingDataDisplay } from '../../components/ScrollingDataDisplay'
import Box from '@mui/material/Box'
import { CopyToClipboard } from '../../components/CopyToClipboard'
import { useScreenSize } from '../../hooks/useScreensize'

export const contractCodeContainerId = 'code'

const CodeDisplay: FC<{ code: string | undefined; label: string; extraTopPadding?: boolean }> = ({
code,
label,
extraTopPadding,
}) => {
const { t } = useTranslation()
const { isMobile } = useScreenSize()
return code === undefined ? null : (
<>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
my: 3,
pt: extraTopPadding ? 4 : 0,
}}
>
<Typography variant="h4" component="h4">
{label}
</Typography>
<CopyToClipboard
value={code}
label={isMobile ? t('common.copy') : t('contract.copyButton', { subject: label })}
/>
</Box>

<ScrollingDataDisplay data={code} />
</>
)
}

export const ContractCodeCard: FC = () => {
const { t } = useTranslation()
const scope = useRequiredScopeParam()
const address = useLoaderData() as string

const { isFetched, account } = useAccount(scope, address)
const contract = account?.evm_contract
const noCode = isFetched && !contract?.creation_bytecode && !contract?.runtime_bytecode
return (
<Card>
<ScrollingDiv id={contractCodeContainerId}>
Comment thread
csillag marked this conversation as resolved.
{noCode && <CardEmptyState label={t('contract.noCode')} />}
{contract && (contract.creation_bytecode || contract.runtime_bytecode) && (
<CardContent>
<CodeDisplay code={contract.creation_bytecode} label={t('contract.creationByteCode')} />
<CodeDisplay
code={contract.runtime_bytecode}
label={t('contract.runtimeByteCode')}
extraTopPadding={!!contract.creation_bytecode}
/>
</CardContent>
)}
</ScrollingDiv>
</Card>
)
}
8 changes: 4 additions & 4 deletions src/app/pages/AccountDetailsPage/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ export const useAccount = (scope: SearchScope, address: string) => {
}
const query = useGetRuntimeAccountsAddress(network, layer, address!)
const account = query.data?.data
const isLoading = query.isLoading
const isError = query.isError
return { account, isLoading, isError }
const { isLoading, isError, isFetched } = query

return { account, isLoading, isError, isFetched }
}

export const useTransactions = (scope: SearchScope, address: string) => {
export const useAccountTransactions = (scope: SearchScope, address: string) => {
const { network, layer } = scope
const pagination = useSearchParamsPagination('page')
const offset = (pagination.selectedPage - 1) * NUMBER_OF_ITEMS_ON_SEPARATE_PAGE
Expand Down
8 changes: 6 additions & 2 deletions src/app/pages/AccountDetailsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import { TokenPriceInfo, useTokenPrice } from '../../../coin-gecko/api'
import { Ticker } from '../../../types/ticker'

import { EvmTokenType, RuntimeAccount } from '../../../oasis-indexer/api'
import { accountTokenContainerId } from './TokensCard'
import { accountTokenContainerId } from './AccountTokensCard'
import { useAccount } from './hook'
import { useRequiredScopeParam } from '../../hooks/useScopeParam'
import { showEmptyAccountDetails } from '../../../config'
import { CardEmptyState } from './CardEmptyState'
import { contractCodeContainerId } from './ContractCodeCard'

export const AccountDetailsPage: FC = () => {
const { t } = useTranslation()
Expand All @@ -29,6 +30,8 @@ export const AccountDetailsPage: FC = () => {
const erc20Link = useHref(`tokens/erc-20#${accountTokenContainerId}`)
const showTxs = showEmptyAccountDetails || showErc20 || !!account?.stats.num_txns
const txLink = useHref('')
const showCode = isContract
const codeLink = useHref(`code#${contractCodeContainerId}`)

const showDetails = showTxs || showErc20

Expand All @@ -50,7 +53,8 @@ export const AccountDetailsPage: FC = () => {
<RouterTabs
tabs={[
{ label: t('common.transactions'), to: txLink, visible: showTxs },
{ label: t('account.ERC20'), to: erc20Link, visible: showErc20 },
{ label: t('common.tokens'), to: erc20Link, visible: showErc20 },
{ label: t('contract.code'), to: codeLink, visible: showCode },
]}
/>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/SearchResultsPage/NoResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const NoResults: FC<{
i18nKey="search.noResults.description"
components={{
OptionalBreak: <OptionalBreak />,
HomeLink: <Link component={RouterLink} to={'/'} />,
HomeLink: <Link component={RouterLink} to="/" />,
}}
/>
</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('SearchResultsView', () => {
hasUsedCoinGecko: false,
},
}}
title={'test search'}
title="test search"
networkForTheme={Network.mainnet}
/>,
)
Expand All @@ -59,7 +59,7 @@ describe('SearchResultsView', () => {
renderWithProviders(
<SearchResultsList
searchResults={[suggestedParsedAccountResult]}
title={'test search'}
title="test search"
networkForTheme={Network.mainnet}
tokenPrices={{
[Network.mainnet]: {
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/SearchResultsPage/notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const HideMoreResults: FC<{ theme: Theme; onHide: () => void }> = ({ them
<NotificationBox theme={theme} onClick={onHide}>
<ZoomOut />
<span>
<Trans i18nKey={'search.otherResults.clickToHide'} />
<Trans i18nKey="search.otherResults.clickToHide" />
</span>
</NotificationBox>
)
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/TransactionDetailPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const TransactionDetailPage: FC = () => {
return (
<PageLayout>
{warningMultipleTransactionsSameHash && (
<StyledAlert severity={'error'}>{t('transaction.warningMultipleTransactionsSameHash')}</StyledAlert>
<StyledAlert severity="error">{t('transaction.warningMultipleTransactionsSameHash')}</StyledAlert>
)}
<SubPageCard
featured
Expand Down
Loading