Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suave customization #1256

Merged
merged 12 commits into from
Oct 9, 2023
3 changes: 3 additions & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,9 @@ const schema = yup
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: yup.string(),
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: yup.string(),
NEXT_PUBLIC_FAVICON_GENERATOR_API_KEY: yup.string(),

// Misc
NEXT_PUBLIC_USE_NEXT_JS_PROXY: yup.boolean(),
})
.concat(accountSchema)
.concat(adsBannerSchema)
Expand Down
2 changes: 2 additions & 0 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ frontend:
exact:
# - "/(apps|auth/profile|account)"
- "/"
- "/envs.js"
prefix:
- "/_next"
- "/node-api"
- "/account"
- "/apps"
- "/static"
- "/assets"
- "/favicon"
- "/auth/profile"
- "/auth/unverified-email"
Expand Down
8 changes: 7 additions & 1 deletion lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ export const RESOURCES = {
path: '/api/v2/transactions/watchlist',
filterFields: [ ],
},
txs_execution_node: {
path: '/api/v2/transactions/execution-node/:hash',
pathParams: [ 'hash' as const ],
filterFields: [ ],
},
tx: {
path: '/api/v2/transactions/:hash',
pathParams: [ 'hash' as const ],
Expand Down Expand Up @@ -533,7 +538,7 @@ export interface ResourceError<T = unknown> {
export type ResourceErrorAccount<T> = ResourceError<{ errors: T }>

export type PaginatedResources = 'blocks' | 'block_txs' |
'txs_validated' | 'txs_pending' | 'txs_watchlist' |
'txs_validated' | 'txs_pending' | 'txs_watchlist' | 'txs_execution_node' |
'tx_internal_txs' | 'tx_logs' | 'tx_token_transfers' | 'tx_state_changes' |
'addresses' |
'address_txs' | 'address_internal_txs' | 'address_token_transfers' | 'address_blocks_validated' | 'address_coin_balance' |
Expand Down Expand Up @@ -577,6 +582,7 @@ Q extends 'block_withdrawals' ? BlockWithdrawalsResponse :
Q extends 'txs_validated' ? TransactionsResponseValidated :
Q extends 'txs_pending' ? TransactionsResponsePending :
Q extends 'txs_watchlist' ? TransactionsResponseWatchlist :
Q extends 'txs_execution_node' ? TransactionsResponseValidated :
Q extends 'tx' ? Transaction :
Q extends 'tx_internal_txs' ? InternalTransactionsResponse :
Q extends 'tx_logs' ? LogsResponseTx :
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/getPageOgType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type OGPageType = 'Homepage' | 'Root page' | 'Regular page';
const OG_TYPE_DICT: Record<Route['pathname'], OGPageType> = {
'/': 'Homepage',
'/txs': 'Root page',
'/txs/computor/[hash]': 'Regular page',
'/tx/[hash]': 'Regular page',
'/blocks': 'Root page',
'/block/[height_or_hash]': 'Regular page',
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const DEFAULT_TEMPLATE = 'Blockscout is the #1 open-source blockchain explorer a
const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/': DEFAULT_TEMPLATE,
'/txs': DEFAULT_TEMPLATE,
'/txs/computor/[hash]': DEFAULT_TEMPLATE,
'/tx/[hash]': 'View transaction %hash% on %network_title%',
'/blocks': DEFAULT_TEMPLATE,
'/block/[height_or_hash]': 'View the transactions, token transfers, and uncles for block %height_or_hash%',
Expand Down
1 change: 1 addition & 0 deletions lib/metadata/templates/title.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Route } from 'nextjs-routes';
const TEMPLATE_MAP: Record<Route['pathname'], string> = {
'/': 'blockchain explorer',
'/txs': 'transactions',
'/txs/computor/[hash]': 'computor %hash% transactions',
'/tx/[hash]': 'transaction %hash%',
'/blocks': 'blocks',
'/block/[height_or_hash]': 'block %height_or_hash%',
Expand Down
1 change: 1 addition & 0 deletions lib/mixpanel/getPageType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Route } from 'nextjs-routes';
export const PAGE_TYPE_DICT: Record<Route['pathname'], string> = {
'/': 'Homepage',
'/txs': 'Transactions',
'/txs/computor/[hash]': 'Computor transactions',
'/tx/[hash]': 'Transaction details',
'/blocks': 'Blocks',
'/block/[height_or_hash]': 'Block details',
Expand Down
1 change: 1 addition & 0 deletions nextjs/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ declare module "nextjs-routes" {
| DynamicRoute<"/token/[hash]/instance/[id]", { "hash": string; "id": string }>
| StaticRoute<"/tokens">
| DynamicRoute<"/tx/[hash]", { "hash": string }>
| DynamicRoute<"/txs/computor/[hash]", { "hash": string }>
| StaticRoute<"/txs">
| StaticRoute<"/verified-contracts">
| StaticRoute<"/visualize/sol2uml">
Expand Down
20 changes: 20 additions & 0 deletions pages/txs/computor/[hash].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';

import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';

const ComputorTxs = dynamic(() => import('ui/pages/ComputorTxs'), { ssr: false });

const Page: NextPage<Props> = (props: Props) => {
return (
<PageNextJs pathname="/txs/computor/[hash]" query={ props }>
<ComputorTxs/>
</PageNextJs>
);
};

export default Page;

export { base as getServerSideProps } from 'nextjs/getServerSideProps';
tom2drum marked this conversation as resolved.
Show resolved Hide resolved
File renamed without changes.
7 changes: 7 additions & 0 deletions types/api/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export type TransactionRevertReason = {
raw: string;
} | DecodedInput;

type WrappedTransactionFields = 'decoded_input' | 'fee' | 'gas_limit' | 'gas_price' | 'hash' | 'max_fee_per_gas' |
'max_priority_fee_per_gas' | 'method' | 'nonce' | 'raw_input' | 'to' | 'type' | 'value';

export type Transaction = {
to: AddressParam | null;
created_contract: AddressParam | null;
Expand Down Expand Up @@ -48,6 +51,10 @@ export type Transaction = {
l1_gas_price?: string;
l1_gas_used?: string;
has_error_in_internal_txs: boolean | null;
// SUAVE fields
execution_node?: AddressParam | null;
allowed_peekers?: Array<string>;
wrapped?: Pick<Transaction, WrappedTransactionFields>;
}

export type TransactionsResponse = TransactionsResponseValidated | TransactionsResponsePending;
Expand Down
2 changes: 2 additions & 0 deletions types/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ export type ArrayElement<ArrType> = ArrType extends ReadonlyArray<infer ElementT

export type ExcludeNull<T> = T extends null ? never : T;

export type ExcludeUndefined<T> = T extends undefined ? never : T;

export type KeysOfObjectOrNull<T> = keyof ExcludeNull<T>;
14 changes: 3 additions & 11 deletions ui/block/BlockDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import Icon from 'ui/shared/chakra/Icon';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import GasUsedToTargetRatio from 'ui/shared/GasUsedToTargetRatio';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
Expand Down Expand Up @@ -81,15 +82,6 @@ const BlockDetails = ({ query }: Props) => {
return null;
}

const sectionGap = (
<GridItem
colSpan={{ base: undefined, lg: 2 }}
mt={{ base: 2, lg: 3 }}
mb={{ base: 0, lg: 3 }}
borderBottom="1px solid"
borderColor="divider"
/>
);
const { totalReward, staticReward, burntFees, txFees } = getBlockReward(data);

const validatorTitle = getNetworkValidatorTitle();
Expand Down Expand Up @@ -243,7 +235,7 @@ const BlockDetails = ({ query }: Props) => {
))
}

{ sectionGap }
<DetailsInfoItemDivider/>

<DetailsInfoItem
title="Gas used"
Expand Down Expand Up @@ -442,7 +434,7 @@ const BlockDetails = ({ query }: Props) => {
</Box>
</DetailsInfoItem>

{ sectionGap }
<DetailsInfoItemDivider/>

<DetailsInfoItem
title="Hash"
Expand Down
42 changes: 42 additions & 0 deletions ui/pages/ComputorTxs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useRouter } from 'next/router';
import React from 'react';

import getQueryParamString from 'lib/router/getQueryParamString';
import { TX } from 'stubs/tx';
import { generateListStub } from 'stubs/utils';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import PageTitle from 'ui/shared/Page/PageTitle';
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
import TxsContent from 'ui/txs/TxsContent';

const ComputorTxs = () => {
const router = useRouter();

const hash = getQueryParamString(router.query.hash);

const query = useQueryWithPages({
resourceName: 'txs_execution_node',
pathParams: { hash },
options: {
placeholderData: generateListStub<'txs_execution_node'>(TX, 50, { next_page_params: {
block_number: 9005713,
index: 5,
items_count: 50,
filter: 'validated',
} }),
},
});

return (
<>
<PageTitle title="Computor transactions" withTextAd/>
<AddressEntity address={{ hash }} mb={ 6 }/>
<TxsContent
query={ query }
showSocketInfo={ false }
/>
</>
);
};

export default ComputorTxs;
31 changes: 21 additions & 10 deletions ui/pages/Transaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,16 @@ import EntityTags from 'ui/shared/EntityTags';
import NetworkExplorers from 'ui/shared/NetworkExplorers';
import PageTitle from 'ui/shared/Page/PageTitle';
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
import useTabIndexFromQuery from 'ui/shared/Tabs/useTabIndexFromQuery';
import TxDetails from 'ui/tx/TxDetails';
import TxDetailsWrapped from 'ui/tx/TxDetailsWrapped';
import TxInternals from 'ui/tx/TxInternals';
import TxLogs from 'ui/tx/TxLogs';
import TxRawTrace from 'ui/tx/TxRawTrace';
import TxState from 'ui/tx/TxState';
import TxTokenTransfer from 'ui/tx/TxTokenTransfer';

const TABS: Array<RoutedTab> = [
{ id: 'index', title: 'Details', component: <TxDetails/> },
{ id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer/> },
{ id: 'internal', title: 'Internal txns', component: <TxInternals/> },
{ id: 'logs', title: 'Logs', component: <TxLogs/> },
{ id: 'state', title: 'State', component: <TxState/> },
{ id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace/> },
];

const TransactionPageContent = () => {
const router = useRouter();
const appProps = useAppContext();
Expand All @@ -44,6 +38,18 @@ const TransactionPageContent = () => {
},
});

const tabs: Array<RoutedTab> = [
{ id: 'index', title: data?.wrapped ? 'Confidential compute tx details' : 'Details', component: <TxDetails/> },
data?.wrapped ? { id: 'wrapped', title: 'Regular tx details', component: <TxDetailsWrapped data={ data.wrapped }/> } : undefined,
{ id: 'token_transfers', title: 'Token transfers', component: <TxTokenTransfer/> },
{ id: 'internal', title: 'Internal txns', component: <TxInternals/> },
{ id: 'logs', title: 'Logs', component: <TxLogs/> },
{ id: 'state', title: 'State', component: <TxState/> },
{ id: 'raw_trace', title: 'Raw trace', component: <TxRawTrace/> },
].filter(Boolean);

const tabIndex = useTabIndexFromQuery(tabs);

const tags = (
<EntityTags
isLoading={ isPlaceholderData }
Expand Down Expand Up @@ -75,7 +81,12 @@ const TransactionPageContent = () => {
backLink={ backLink }
contentAfter={ tags }
/>
<RoutedTabs tabs={ TABS }/>
{ isPlaceholderData ? (
<>
<TabsSkeleton tabs={ tabs } mt={ 6 }/>
{ tabs[tabIndex]?.component }
</>
) : <RoutedTabs tabs={ tabs }/> }
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { GridItem } from '@chakra-ui/react';
import React from 'react';

const TokenInstanceDivider = () => {
const DetailsInfoItemDivider = () => {
return (
<GridItem
colSpan={{ base: undefined, lg: 2 }}
Expand All @@ -13,4 +13,4 @@ const TokenInstanceDivider = () => {
);
};

export default TokenInstanceDivider;
export default DetailsInfoItemDivider;
4 changes: 2 additions & 2 deletions ui/tokenInstance/TokenInstanceDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import type { TokenInstance } from 'types/api/token';

import CopyToClipboard from 'ui/shared/CopyToClipboard';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import NftMedia from 'ui/shared/nft/NftMedia';

import TokenInstanceCreatorAddress from './details/TokenInstanceCreatorAddress';
import TokenInstanceDivider from './details/TokenInstanceDivider';
import TokenInstanceMetadataInfo from './details/TokenInstanceMetadataInfo';
import TokenInstanceTransfersCount from './details/TokenInstanceTransfersCount';

Expand Down Expand Up @@ -99,7 +99,7 @@ const TokenInstanceDetails = ({ data, scrollRef, isLoading }: Props) => {
overflow="hidden"
>
<TokenInstanceMetadataInfo data={ data } isLoading={ isLoading }/>
<TokenInstanceDivider/>
<DetailsInfoItemDivider/>
<DetailsSponsoredItem isLoading={ isLoading }/>
</Grid>
</>
Expand Down
5 changes: 2 additions & 3 deletions ui/tokenInstance/details/TokenInstanceMetadataInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ import type { MetadataAttributes } from 'types/client/token';

import parseMetadata from 'lib/token/parseMetadata';
import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
import LinkExternal from 'ui/shared/LinkExternal';
import TruncatedValue from 'ui/shared/TruncatedValue';

import TokenInstanceDivider from './TokenInstanceDivider';

interface Props {
data?: TokenInstance;
isLoading?: boolean;
Expand Down Expand Up @@ -71,7 +70,7 @@ const TokenInstanceMetadataInfo = ({ data, isLoading }: Props) => {

return (
<>
<TokenInstanceDivider/>
<DetailsInfoItemDivider/>
{ metadata?.name && (
<DetailsInfoItem
title="Name"
Expand Down
41 changes: 41 additions & 0 deletions ui/tx/TxAllowedPeekers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Flex, Link, useBoolean } from '@chakra-ui/react';
import React from 'react';

import DetailsInfoItem from 'ui/shared/DetailsInfoItem';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';

interface Props {
items: Array<string>;
}

const CUT_LENGTH = 2;

const TxAllowedPeekers = ({ items }: Props) => {
const [ isExpanded, expand ] = useBoolean(false);

return (
<DetailsInfoItem
title="Allowed peekers"
hint="Smart contracts allowed to interact with confidential data"
>
<Flex flexDir="column" rowGap={ 3 } w="100%">
{ items
.slice(0, isExpanded ? undefined : CUT_LENGTH)
.map((item) => <AddressEntity key={ item } address={{ hash: item, is_contract: true }}/>) }
</Flex>
{ items.length > CUT_LENGTH && (
<Link
display="inline-block"
fontSize="sm"
textDecorationLine="underline"
textDecorationStyle="dashed"
onClick={ expand.toggle }
>
{ isExpanded ? 'Hide' : 'Show all' }
</Link>
) }
</DetailsInfoItem>
);
};

export default React.memo(TxAllowedPeekers);
Loading