Refactor rollup features (#1599)
* refactor ENVs and app feature * rename l2 into optimisticL2 * [skip ci] fix validator schema
@@ -13,7 +13,7 @@ export { default as marketplace } from './marketplace';
|
||||
export { default as mixpanel } from './mixpanel';
|
||||
export { default as nameService } from './nameService';
|
||||
export { default as restApiDocs } from './restApiDocs';
|
||||
export { default as optimisticRollup } from './optimisticRollup';
|
||||
export { default as rollup } from './rollup';
|
||||
export { default as safe } from './safe';
|
||||
export { default as sentry } from './sentry';
|
||||
export { default as sol2uml } from './sol2uml';
|
||||
@@ -23,4 +23,3 @@ export { default as txInterpretation } from './txInterpretation';
|
||||
export { default as userOps } from './userOps';
|
||||
export { default as verifiedTokens } from './verifiedTokens';
|
||||
export { default as web3Wallet } from './web3Wallet';
|
||||
export { default as zkEvmRollup } from './zkEvmRollup';
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import type { Feature } from './types';
|
||||
|
||||
import { getEnvValue } from '../utils';
|
||||
|
||||
const title = 'Rollup (L2) chain';
|
||||
|
||||
const config: Feature<{ L1BaseUrl: string; withdrawalUrl: string }> = (() => {
|
||||
const L1BaseUrl = getEnvValue('NEXT_PUBLIC_L1_BASE_URL');
|
||||
const withdrawalUrl = getEnvValue('NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL');
|
||||
|
||||
if (
|
||||
getEnvValue('NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK') === 'true' &&
|
||||
L1BaseUrl &&
|
||||
withdrawalUrl
|
||||
) {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
L1BaseUrl,
|
||||
withdrawalUrl,
|
||||
});
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: false,
|
||||
});
|
||||
})();
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { Feature } from './types';
|
||||
import type { RollupType } from 'types/client/rollup';
|
||||
import { ROLLUP_TYPES } from 'types/client/rollup';
|
||||
|
||||
import { getEnvValue } from '../utils';
|
||||
|
||||
const type = (() => {
|
||||
const envValue = getEnvValue('NEXT_PUBLIC_ROLLUP_TYPE');
|
||||
return ROLLUP_TYPES.find((type) => type === envValue);
|
||||
})();
|
||||
|
||||
const L1BaseUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L1_BASE_URL');
|
||||
const L2WithdrawalUrl = getEnvValue('NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL');
|
||||
|
||||
const title = 'Rollup (L2) chain';
|
||||
|
||||
const config: Feature<{ type: RollupType; L1BaseUrl: string; L2WithdrawalUrl?: string }> = (() => {
|
||||
|
||||
if (type && L1BaseUrl) {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
type,
|
||||
L1BaseUrl,
|
||||
L2WithdrawalUrl,
|
||||
});
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: false,
|
||||
});
|
||||
})();
|
||||
|
||||
export default config;
|
||||
@@ -1,25 +0,0 @@
|
||||
import type { Feature } from './types';
|
||||
|
||||
import { getEnvValue } from '../utils';
|
||||
|
||||
const title = 'ZkEVM rollup (L2) chain';
|
||||
|
||||
const config: Feature<{ L1BaseUrl: string; withdrawalUrl?: string }> = (() => {
|
||||
const L1BaseUrl = getEnvValue('NEXT_PUBLIC_L1_BASE_URL');
|
||||
const isZkEvm = getEnvValue('NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK') === 'true';
|
||||
|
||||
if (isZkEvm && L1BaseUrl) {
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: true,
|
||||
L1BaseUrl,
|
||||
});
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
title,
|
||||
isEnabled: false,
|
||||
});
|
||||
})();
|
||||
|
||||
export default config;
|
||||
@@ -44,8 +44,6 @@ NEXT_PUBLIC_APP_INSTANCE=jest
|
||||
NEXT_PUBLIC_APP_ENV=testing
|
||||
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://localhost:3000/marketplace-config.json
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://localhost:3000/marketplace-submit-form
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK=false
|
||||
NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK=false
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_AUTH_URL=http://localhost:3100
|
||||
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
|
||||
|
||||
@@ -47,6 +47,6 @@ NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
|
||||
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace/base-goerli.json
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/shrqUAcjgGJ4jU88C
|
||||
NEXT_PUBLIC_STATS_API_HOST=https://stats-optimism-goerli.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK=true
|
||||
NEXT_PUBLIC_L1_BASE_URL=https://blockscout-main.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://blockscout-main.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
|
||||
|
||||
@@ -41,8 +41,6 @@ NEXT_PUBLIC_APP_ENV=testing
|
||||
NEXT_PUBLIC_APP_INSTANCE=pw
|
||||
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://localhost:3000/marketplace-config.json
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://localhost:3000/marketplace-submit-form
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK=false
|
||||
NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK=false
|
||||
NEXT_PUBLIC_AD_BANNER_PROVIDER=slise
|
||||
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
|
||||
NEXT_PUBLIC_AUTH_URL=http://localhost:3100
|
||||
|
||||
@@ -47,5 +47,5 @@ NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
|
||||
# rollup
|
||||
NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK=true
|
||||
NEXT_PUBLIC_L1_BASE_URL=https://polygon.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_TYPE=zkEvm
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://polygon.blockscout.com
|
||||
|
||||
@@ -15,6 +15,7 @@ import type { ContractCodeIde } from '../../../types/client/contract';
|
||||
import type { MarketplaceAppOverview } from '../../../types/client/marketplace';
|
||||
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation-items';
|
||||
import type { NavItemExternal, NavigationLinkId } from '../../../types/client/navigation-items';
|
||||
import { ROLLUP_TYPES } from '../../../types/client/rollup';
|
||||
import type { BridgedTokenChain, TokenBridge } from '../../../types/client/token';
|
||||
import { PROVIDERS as TX_INTERPRETATION_PROVIDERS } from '../../../types/client/txInterpretation';
|
||||
import type { WalletType } from '../../../types/client/wallets';
|
||||
@@ -114,23 +115,20 @@ const beaconChainSchema = yup
|
||||
const rollupSchema = yup
|
||||
.object()
|
||||
.shape({
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK: yup.boolean(),
|
||||
NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL: yup
|
||||
NEXT_PUBLIC_ROLLUP_TYPE: yup.string().oneOf(ROLLUP_TYPES),
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: yup
|
||||
.string()
|
||||
.when('NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK', {
|
||||
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
|
||||
is: (value: string) => value,
|
||||
then: (schema) => schema.test(urlTest).required(),
|
||||
// eslint-disable-next-line max-len
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL cannot not be used if NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK is not set to "true"'),
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined'),
|
||||
}),
|
||||
NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK: yup.boolean(),
|
||||
NEXT_PUBLIC_L1_BASE_URL: yup
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: yup
|
||||
.string()
|
||||
.when([ 'NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK', 'NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK' ], {
|
||||
is: (isOptimistic?: boolean, isZk?: boolean) => isOptimistic || isZk,
|
||||
.when('NEXT_PUBLIC_ROLLUP_TYPE', {
|
||||
is: (value: string) => value === 'optimistic',
|
||||
then: (schema) => schema.test(urlTest).required(),
|
||||
// eslint-disable-next-line max-len
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_L1_BASE_URL cannot not be used if NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK or NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK is not set to "true"'),
|
||||
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL cannot not be used if NEXT_PUBLIC_ROLLUP_TYPE is not defined'),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK=true
|
||||
NEXT_PUBLIC_L1_BASE_URL=https://example.com
|
||||
NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL=https://example.com
|
||||
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://example.com
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://example.com
|
||||
@@ -191,9 +191,9 @@ frontend:
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://visualizer-test.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://contracts-info-test.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://admin-rs-test.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK: "true"
|
||||
NEXT_PUBLIC_L1_BASE_URL: https://eth-goerli.blockscout.com/
|
||||
NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL: https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_ROLLUP_TYPE: optimistic
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: https://eth-goerli.blockscout.com/
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: 0x4a0ed8ddf751a7cb5297f827699117b0f6d21a0b2907594d300dc9fed75c7e62
|
||||
envFromSecret:
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID: ref+vault://deployment-values/blockscout/dev/front-main?token_env=VAULT_TOKEN&address=https://vault.k8s.blockscout.com#/NEXT_PUBLIC_AUTH0_CLIENT_ID
|
||||
|
||||
@@ -65,9 +65,9 @@ frontend:
|
||||
NEXT_PUBLIC_VISUALIZE_API_HOST: https://visualizer-optimism-goerli.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://contracts-info-test.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://admin-rs-test.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK: "true"
|
||||
NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL: https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_L1_BASE_URL: https://blockscout-main.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_TYPE=optimistic
|
||||
NEXT_PUBLIC_ROLLUP_L1_BASE_URL=https://blockscout-main.k8s-dev.blockscout.com
|
||||
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL=https://app.optimism.io/bridge/withdraw
|
||||
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: 0x4a0ed8ddf751a7cb5297f827699117b0f6d21a0b2907594d300dc9fed75c7e62
|
||||
NEXT_PUBLIC_USE_NEXT_JS_PROXY: true
|
||||
envFromSecret:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# Deprecated environment variables
|
||||
|
||||
| Variable | Type | Description | Compulsoriness | Default value | Example value | Deprecated in version | Comment |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK | `boolean` | Set to true for optimistic L2 solutions | Required | - | `true` | v1.24.0 | Replaced by NEXT_PUBLIC_ROLLUP_TYPE |
|
||||
| NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK | `boolean` | Set to true for zkevm L2 solutions | Required | - | `true` | v1.24.0 | Replaced by NEXT_PUBLIC_ROLLUP_TYPE |
|
||||
| NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL | `string` | URL for optimistic L2 -> L1 withdrawals | Required | - | `https://app.optimism.io/bridge/withdraw` | v1.24.0 | Renamed to NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL |
|
||||
| NEXT_PUBLIC_L1_BASE_URL | `string` | Blockscout base URL for L1 network | Required | - | `'http://eth-goerli.blockscout.com'` | v1.24.0 | Renamed to NEXT_PUBLIC_ROLLUP_L1_BASE_URL |
|
||||
@@ -34,8 +34,7 @@ Please be aware that all environment variables prefixed with `NEXT_PUBLIC_` will
|
||||
- [Text ads](ENVS.md#text-ads)
|
||||
- [Beacon chain](ENVS.md#beacon-chain)
|
||||
- [User operations](ENVS.md#user-operations-feature-erc-4337)
|
||||
- [Optimistic rollup (L2) chain](ENVS.md#optimistic-rollup-l2-chain)
|
||||
- [ZkEvm rollup (L2) chain](NVS.md#zkevm-rollup-l2-chain)
|
||||
- [Rollup chain](ENVS.md#rollup-chain)
|
||||
- [Export data to CSV file](ENVS.md#export-data-to-csv-file)
|
||||
- [Google analytics](ENVS.md#google-analytics)
|
||||
- [Mixpanel analytics](ENVS.md#mixpanel-analytics)
|
||||
@@ -365,22 +364,13 @@ This feature is **enabled by default** with the `coinzilla` ads provider. To swi
|
||||
|
||||
|
||||
|
||||
### Optimistic rollup (L2) chain
|
||||
### Rollup chain
|
||||
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK | `boolean` | Set to true for optimistic L2 solutions | Required | - | `true` |
|
||||
| NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL | `string` | URL for optimistic L2 -> L1 withdrawals | Required | - | `https://app.optimism.io/bridge/withdraw` |
|
||||
| NEXT_PUBLIC_L1_BASE_URL | `string` | Blockscout base URL for L1 network | Required | - | `'http://eth-goerli.blockscout.com'` |
|
||||
|
||||
|
||||
|
||||
### ZkEvm rollup (L2) chain
|
||||
| Variable | Type| Description | Compulsoriness | Default value | Example value |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK | `boolean` | Set to true for zkevm L2 solutions | Required | - | `true` |
|
||||
| NEXT_PUBLIC_L1_BASE_URL | `string` | Blockscout base URL for L1 network | Required | - | `'http://eth-goerli.blockscout.com'` |
|
||||
|
||||
| NEXT_PUBLIC_ROLLUP_TYPE | `'optimistic' \| 'zkEvm' ` | Rollup chain type | Required | - | `'optimistic'` |
|
||||
| NEXT_PUBLIC_ROLLUP_L1_BASE_URL | `string` | Blockscout base URL for L1 network | Required | - | `'http://eth-goerli.blockscout.com'` |
|
||||
| NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL | `string` | URL for L2 -> L1 withdrawals | - | - | `https://app.optimism.io/bridge/withdraw` |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -47,11 +47,14 @@ import type {
|
||||
} from 'types/api/ens';
|
||||
import type { IndexingStatus } from 'types/api/indexingStatus';
|
||||
import type { InternalTransactionsResponse } from 'types/api/internalTransaction';
|
||||
import type { L2DepositsResponse, L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { L2OutputRootsResponse } from 'types/api/l2OutputRoots';
|
||||
import type { L2TxnBatchesResponse } from 'types/api/l2TxnBatches';
|
||||
import type { L2WithdrawalsResponse } from 'types/api/l2Withdrawals';
|
||||
import type { LogsResponseTx, LogsResponseAddress } from 'types/api/log';
|
||||
import type {
|
||||
OptimisticL2DepositsResponse,
|
||||
OptimisticL2DepositsItem,
|
||||
OptimisticL2OutputRootsResponse,
|
||||
OptimisticL2TxnBatchesResponse,
|
||||
OptimisticL2WithdrawalsResponse,
|
||||
} from 'types/api/optimisticL2';
|
||||
import type { RawTracesResponse } from 'types/api/rawTrace';
|
||||
import type { SearchRedirectResult, SearchResult, SearchResultFilters, SearchResultItem } from 'types/api/search';
|
||||
import type { Counters, StatsCharts, StatsChart, HomeStats } from 'types/api/stats';
|
||||
@@ -81,7 +84,7 @@ import type { UserOpsResponse, UserOp, UserOpsFilters, UserOpsAccount } from 'ty
|
||||
import type { VerifiedContractsSorting } from 'types/api/verifiedContracts';
|
||||
import type { VisualizedContract } from 'types/api/visualization';
|
||||
import type { WithdrawalsResponse, WithdrawalsCounters } from 'types/api/withdrawals';
|
||||
import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem, ZkEvmL2TxnBatchesResponse, ZkEvmL2TxnBatchTxs } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem, ZkEvmL2TxnBatchesResponse, ZkEvmL2TxnBatchTxs } from 'types/api/zkEvmL2';
|
||||
import type { ArrayElement } from 'types/utils';
|
||||
|
||||
import config from 'configs/app';
|
||||
@@ -688,7 +691,7 @@ Q extends 'homepage_chart_market' ? ChartMarketResponse :
|
||||
Q extends 'homepage_blocks' ? Array<Block> :
|
||||
Q extends 'homepage_txs' ? Array<Transaction> :
|
||||
Q extends 'homepage_txs_watchlist' ? Array<Transaction> :
|
||||
Q extends 'homepage_deposits' ? Array<L2DepositsItem> :
|
||||
Q extends 'homepage_deposits' ? Array<OptimisticL2DepositsItem> :
|
||||
Q extends 'homepage_zkevm_l2_batches' ? { items: Array<ZkEvmL2TxnBatchesItem> } :
|
||||
Q extends 'homepage_indexing_status' ? IndexingStatus :
|
||||
Q extends 'homepage_zkevm_latest_batch' ? number :
|
||||
@@ -752,10 +755,10 @@ Q extends 'visualize_sol2uml' ? VisualizedContract :
|
||||
Q extends 'contract_verification_config' ? SmartContractVerificationConfig :
|
||||
Q extends 'withdrawals' ? WithdrawalsResponse :
|
||||
Q extends 'withdrawals_counters' ? WithdrawalsCounters :
|
||||
Q extends 'l2_output_roots' ? L2OutputRootsResponse :
|
||||
Q extends 'l2_withdrawals' ? L2WithdrawalsResponse :
|
||||
Q extends 'l2_deposits' ? L2DepositsResponse :
|
||||
Q extends 'l2_txn_batches' ? L2TxnBatchesResponse :
|
||||
Q extends 'l2_output_roots' ? OptimisticL2OutputRootsResponse :
|
||||
Q extends 'l2_withdrawals' ? OptimisticL2WithdrawalsResponse :
|
||||
Q extends 'l2_deposits' ? OptimisticL2DepositsResponse :
|
||||
Q extends 'l2_txn_batches' ? OptimisticL2TxnBatchesResponse :
|
||||
Q extends 'l2_output_roots_count' ? number :
|
||||
Q extends 'l2_withdrawals_count' ? number :
|
||||
Q extends 'l2_deposits_count' ? number :
|
||||
|
||||
@@ -67,7 +67,9 @@ export default function useNavItems(): ReturnType {
|
||||
isActive: pathname === '/name-domains' || pathname === '/name-domains/[name]',
|
||||
} : null;
|
||||
|
||||
if (config.features.zkEvmRollup.isEnabled) {
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
if (rollupFeature.isEnabled && rollupFeature.type === 'zkEvm') {
|
||||
blockchainNavItems = [
|
||||
[
|
||||
txs,
|
||||
@@ -86,7 +88,7 @@ export default function useNavItems(): ReturnType {
|
||||
ensLookup,
|
||||
].filter(Boolean),
|
||||
];
|
||||
} else if (config.features.optimisticRollup.isEnabled) {
|
||||
} else if (rollupFeature.isEnabled && rollupFeature.type === 'optimistic') {
|
||||
blockchainNavItems = [
|
||||
[
|
||||
txs,
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { SmartContractVerificationResponse } from 'types/api/contract';
|
||||
import type { RawTracesResponse } from 'types/api/rawTrace';
|
||||
import type { TokenTransfer } from 'types/api/tokenTransfer';
|
||||
import type { Transaction } from 'types/api/transaction';
|
||||
import type { NewZkEvmBatchSocketResponse } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { NewZkEvmBatchSocketResponse } from 'types/api/zkEvmL2';
|
||||
|
||||
export type SocketMessageParams = SocketMessage.NewBlock |
|
||||
SocketMessage.BlocksIndexStatus |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ZkEvmL2TxnBatch } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatch } from 'types/api/zkEvmL2';
|
||||
|
||||
export const txnBatchData: ZkEvmL2TxnBatch = {
|
||||
acc_input_hash: '0x4bf88aabe33713b7817266d7860912c58272d808da7397cdc627ca53b296fad3',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ZkEvmL2TxnBatchesResponse } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesResponse } from 'types/api/zkEvmL2';
|
||||
|
||||
export const txnBatchesData: ZkEvmL2TxnBatchesResponse = {
|
||||
items: [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { GetServerSideProps } from 'next';
|
||||
|
||||
import config from 'configs/app';
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
export type Props = {
|
||||
cookies: string;
|
||||
@@ -49,7 +50,10 @@ export const verifiedAddresses: GetServerSideProps<Props> = async(context) => {
|
||||
};
|
||||
|
||||
export const withdrawals: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.beaconChain.isEnabled && !config.features.optimisticRollup.isEnabled) {
|
||||
if (
|
||||
!config.features.beaconChain.isEnabled &&
|
||||
!(rollupFeature.isEnabled && rollupFeature.type === 'optimistic')
|
||||
) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
@@ -59,7 +63,7 @@ export const withdrawals: GetServerSideProps<Props> = async(context) => {
|
||||
};
|
||||
|
||||
export const rollup: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.optimisticRollup.isEnabled && !config.features.zkEvmRollup.isEnabled) {
|
||||
if (!config.features.rollup.isEnabled) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
@@ -69,7 +73,7 @@ export const rollup: GetServerSideProps<Props> = async(context) => {
|
||||
};
|
||||
|
||||
export const optimisticRollup: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.optimisticRollup.isEnabled) {
|
||||
if (!(rollupFeature.isEnabled && rollupFeature.type === 'optimistic')) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
@@ -79,7 +83,7 @@ export const optimisticRollup: GetServerSideProps<Props> = async(context) => {
|
||||
};
|
||||
|
||||
export const zkEvmRollup: GetServerSideProps<Props> = async(context) => {
|
||||
if (!config.features.zkEvmRollup.isEnabled) {
|
||||
if (!(rollupFeature.isEnabled && rollupFeature.type === 'zkEvm')) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
|
||||
@@ -38,9 +38,9 @@ declare module "nextjs-routes" {
|
||||
| StaticRoute<"/login">
|
||||
| DynamicRoute<"/name-domains/[name]", { "name": string }>
|
||||
| StaticRoute<"/name-domains">
|
||||
| StaticRoute<"/output-roots">
|
||||
| DynamicRoute<"/op/[hash]", { "hash": string }>
|
||||
| StaticRoute<"/ops">
|
||||
| StaticRoute<"/output-roots">
|
||||
| StaticRoute<"/search-results">
|
||||
| StaticRoute<"/stats">
|
||||
| DynamicRoute<"/token/[hash]", { "hash": string }>
|
||||
|
||||
@@ -5,12 +5,19 @@ import React from 'react';
|
||||
import PageNextJs from 'nextjs/PageNextJs';
|
||||
|
||||
import config from 'configs/app';
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const Batches = dynamic(() => {
|
||||
if (config.features.zkEvmRollup.isEnabled) {
|
||||
return import('ui/pages/ZkEvmL2TxnBatches');
|
||||
if (!rollupFeature.isEnabled) {
|
||||
throw new Error('Rollup feature is not enabled.');
|
||||
}
|
||||
|
||||
switch (rollupFeature.type) {
|
||||
case 'zkEvm':
|
||||
return import('ui/pages/ZkEvmL2TxnBatches');
|
||||
case 'optimistic':
|
||||
return import('ui/pages/OptimisticL2TxnBatches');
|
||||
}
|
||||
return import('ui/pages/L2TxnBatches');
|
||||
}, { ssr: false });
|
||||
|
||||
const Page: NextPage = () => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
|
||||
import PageNextJs from 'nextjs/PageNextJs';
|
||||
|
||||
const Deposits = dynamic(() => import('ui/pages/L2Deposits'), { ssr: false });
|
||||
const Deposits = dynamic(() => import('ui/pages/OptimisticL2Deposits'), { ssr: false });
|
||||
|
||||
const Page: NextPage = () => {
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,7 @@ import React from 'react';
|
||||
|
||||
import PageNextJs from 'nextjs/PageNextJs';
|
||||
|
||||
const OutputRoots = dynamic(() => import('ui/pages/L2OutputRoots'), { ssr: false });
|
||||
const OutputRoots = dynamic(() => import('ui/pages/OptimisticL2OutputRoots'), { ssr: false });
|
||||
|
||||
const Page: NextPage = () => {
|
||||
return (
|
||||
|
||||
@@ -5,12 +5,18 @@ import React from 'react';
|
||||
import PageNextJs from 'nextjs/PageNextJs';
|
||||
|
||||
import config from 'configs/app';
|
||||
const rollupFeature = config.features.rollup;
|
||||
const beaconChainFeature = config.features.beaconChain;
|
||||
|
||||
const Withdrawals = dynamic(() => {
|
||||
if (config.features.optimisticRollup.isEnabled) {
|
||||
return import('ui/pages/L2Withdrawals');
|
||||
if (rollupFeature.isEnabled && rollupFeature.type === 'optimistic') {
|
||||
return import('ui/pages/OptimisticL2Withdrawals');
|
||||
}
|
||||
return import('ui/pages/Withdrawals');
|
||||
if (beaconChainFeature.isEnabled) {
|
||||
return import('ui/pages/BeaconChainWithdrawals');
|
||||
}
|
||||
|
||||
throw new Error('Withdrawals feature is not enabled.');
|
||||
}, { ssr: false });
|
||||
|
||||
const Page: NextPage = () => {
|
||||
|
||||
@@ -15,9 +15,9 @@ export const featureEnvs = {
|
||||
{ name: 'NEXT_PUBLIC_HAS_BEACON_CHAIN', value: 'true' },
|
||||
],
|
||||
optimisticRollup: [
|
||||
{ name: 'NEXT_PUBLIC_IS_OPTIMISTIC_L2_NETWORK', value: 'true' },
|
||||
{ name: 'NEXT_PUBLIC_L1_BASE_URL', value: 'https://localhost:3101' },
|
||||
{ name: 'NEXT_PUBLIC_OPTIMISTIC_L2_WITHDRAWAL_URL', value: 'https://localhost:3102' },
|
||||
{ name: 'NEXT_PUBLIC_ROLLUP_TYPE', value: 'optimistic' },
|
||||
{ name: 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', value: 'https://localhost:3101' },
|
||||
{ name: 'NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL', value: 'https://localhost:3102' },
|
||||
],
|
||||
bridgedTokens: [
|
||||
{
|
||||
@@ -32,9 +32,9 @@ export const featureEnvs = {
|
||||
txInterpretation: [
|
||||
{ name: 'NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER', value: 'blockscout' },
|
||||
],
|
||||
zkRollup: [
|
||||
{ name: 'NEXT_PUBLIC_IS_ZKEVM_L2_NETWORK', value: 'true' },
|
||||
{ name: 'NEXT_PUBLIC_L1_BASE_URL', value: 'https://localhost:3101' },
|
||||
zkEvmRollup: [
|
||||
{ name: 'NEXT_PUBLIC_ROLLUP_TYPE', value: 'zkEvm' },
|
||||
{ name: 'NEXT_PUBLIC_ROLLUP_L1_BASE_URL', value: 'https://localhost:3101' },
|
||||
],
|
||||
userOps: [
|
||||
{ name: 'NEXT_PUBLIC_HAS_USER_OPS', value: 'true' },
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import type { L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { L2OutputRootsItem } from 'types/api/l2OutputRoots';
|
||||
import type { L2TxnBatchesItem } from 'types/api/l2TxnBatches';
|
||||
import type { L2WithdrawalsItem } from 'types/api/l2Withdrawals';
|
||||
import type {
|
||||
OptimisticL2DepositsItem,
|
||||
OptimisticL2OutputRootsItem,
|
||||
OptimisticL2TxnBatchesItem,
|
||||
OptimisticL2WithdrawalsItem,
|
||||
} from 'types/api/optimisticL2';
|
||||
|
||||
import { ADDRESS_HASH, ADDRESS_PARAMS } from './addressParams';
|
||||
import { TX_HASH } from './tx';
|
||||
|
||||
export const L2_DEPOSIT_ITEM: L2DepositsItem = {
|
||||
export const L2_DEPOSIT_ITEM: OptimisticL2DepositsItem = {
|
||||
l1_block_number: 9045233,
|
||||
l1_block_timestamp: '2023-05-22T18:00:36.000000Z',
|
||||
l1_tx_hash: TX_HASH,
|
||||
@@ -15,7 +17,7 @@ export const L2_DEPOSIT_ITEM: L2DepositsItem = {
|
||||
l2_tx_hash: TX_HASH,
|
||||
};
|
||||
|
||||
export const L2_WITHDRAWAL_ITEM: L2WithdrawalsItem = {
|
||||
export const L2_WITHDRAWAL_ITEM: OptimisticL2WithdrawalsItem = {
|
||||
challenge_period_end: null,
|
||||
from: ADDRESS_PARAMS,
|
||||
l1_tx_hash: TX_HASH,
|
||||
@@ -26,7 +28,7 @@ export const L2_WITHDRAWAL_ITEM: L2WithdrawalsItem = {
|
||||
status: 'Ready to prove',
|
||||
};
|
||||
|
||||
export const L2_TXN_BATCHES_ITEM: L2TxnBatchesItem = {
|
||||
export const L2_TXN_BATCHES_ITEM: OptimisticL2TxnBatchesItem = {
|
||||
epoch_number: 9103513,
|
||||
l1_timestamp: '2023-06-01T14:46:48.000000Z',
|
||||
l1_tx_hashes: [
|
||||
@@ -36,7 +38,7 @@ export const L2_TXN_BATCHES_ITEM: L2TxnBatchesItem = {
|
||||
tx_count: 9,
|
||||
};
|
||||
|
||||
export const L2_OUTPUT_ROOTS_ITEM: L2OutputRootsItem = {
|
||||
export const L2_OUTPUT_ROOTS_ITEM: OptimisticL2OutputRootsItem = {
|
||||
l1_block_number: 9103684,
|
||||
l1_timestamp: '2023-06-01T15:26:12.000000Z',
|
||||
l1_tx_hash: TX_HASH,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatch, ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { TX_HASH } from './tx';
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
export type L2DepositsItem = {
|
||||
l1_block_number: number;
|
||||
l1_tx_hash: string;
|
||||
l1_block_timestamp: string;
|
||||
l1_tx_origin: string;
|
||||
l2_tx_gas_limit: string;
|
||||
l2_tx_hash: string;
|
||||
}
|
||||
|
||||
export type L2DepositsResponse = {
|
||||
items: Array<L2DepositsItem>;
|
||||
next_page_params: {
|
||||
items_count: number;
|
||||
l1_block_number: number;
|
||||
tx_hash: string;
|
||||
};
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
export type L2OutputRootsItem = {
|
||||
l1_block_number: number;
|
||||
l1_timestamp: string;
|
||||
l1_tx_hash: string;
|
||||
l2_block_number: number;
|
||||
l2_output_index: number;
|
||||
output_root: string;
|
||||
}
|
||||
|
||||
export type L2OutputRootsResponse = {
|
||||
items: Array<L2OutputRootsItem>;
|
||||
next_page_params: {
|
||||
index: number;
|
||||
items_count: number;
|
||||
};
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
export type L2TxnBatchesItem = {
|
||||
epoch_number: number;
|
||||
l1_tx_hashes: Array<string>;
|
||||
l1_timestamp: string;
|
||||
l2_block_number: number;
|
||||
tx_count: number;
|
||||
}
|
||||
|
||||
export type L2TxnBatchesResponse = {
|
||||
items: Array<L2TxnBatchesItem>;
|
||||
next_page_params: {
|
||||
block_number: number;
|
||||
items_count: number;
|
||||
};
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import type { AddressParam } from './addressParams';
|
||||
|
||||
export type L2WithdrawalsItem = {
|
||||
'challenge_period_end': string | null;
|
||||
'from': AddressParam | null;
|
||||
'l1_tx_hash': string | null;
|
||||
'l2_timestamp': string | null;
|
||||
'l2_tx_hash': string;
|
||||
'msg_nonce': number;
|
||||
'msg_nonce_version': number;
|
||||
'status': string;
|
||||
}
|
||||
|
||||
export const WITHDRAWAL_STATUSES = [
|
||||
'Waiting for state root',
|
||||
'Ready to prove',
|
||||
'In challenge period',
|
||||
'Ready for relay',
|
||||
'Relayed',
|
||||
] as const;
|
||||
|
||||
export type L2WithdrawalStatus = typeof WITHDRAWAL_STATUSES[number];
|
||||
|
||||
export type L2WithdrawalsResponse = {
|
||||
items: Array<L2WithdrawalsItem>;
|
||||
'next_page_params': {
|
||||
'items_count': number;
|
||||
'nonce': string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
import type { AddressParam } from './addressParams';
|
||||
|
||||
export type OptimisticL2DepositsItem = {
|
||||
l1_block_number: number;
|
||||
l1_tx_hash: string;
|
||||
l1_block_timestamp: string;
|
||||
l1_tx_origin: string;
|
||||
l2_tx_gas_limit: string;
|
||||
l2_tx_hash: string;
|
||||
}
|
||||
|
||||
export type OptimisticL2DepositsResponse = {
|
||||
items: Array<OptimisticL2DepositsItem>;
|
||||
next_page_params: {
|
||||
items_count: number;
|
||||
l1_block_number: number;
|
||||
tx_hash: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type OptimisticL2OutputRootsItem = {
|
||||
l1_block_number: number;
|
||||
l1_timestamp: string;
|
||||
l1_tx_hash: string;
|
||||
l2_block_number: number;
|
||||
l2_output_index: number;
|
||||
output_root: string;
|
||||
}
|
||||
|
||||
export type OptimisticL2OutputRootsResponse = {
|
||||
items: Array<OptimisticL2OutputRootsItem>;
|
||||
next_page_params: {
|
||||
index: number;
|
||||
items_count: number;
|
||||
};
|
||||
}
|
||||
|
||||
export type OptimisticL2TxnBatchesItem = {
|
||||
epoch_number: number;
|
||||
l1_tx_hashes: Array<string>;
|
||||
l1_timestamp: string;
|
||||
l2_block_number: number;
|
||||
tx_count: number;
|
||||
}
|
||||
|
||||
export type OptimisticL2TxnBatchesResponse = {
|
||||
items: Array<OptimisticL2TxnBatchesItem>;
|
||||
next_page_params: {
|
||||
block_number: number;
|
||||
items_count: number;
|
||||
};
|
||||
}
|
||||
|
||||
export type OptimisticL2WithdrawalsItem = {
|
||||
'challenge_period_end': string | null;
|
||||
'from': AddressParam | null;
|
||||
'l1_tx_hash': string | null;
|
||||
'l2_timestamp': string | null;
|
||||
'l2_tx_hash': string;
|
||||
'msg_nonce': number;
|
||||
'msg_nonce_version': number;
|
||||
'status': string;
|
||||
}
|
||||
|
||||
export const WITHDRAWAL_STATUSES = [
|
||||
'Waiting for state root',
|
||||
'Ready to prove',
|
||||
'In challenge period',
|
||||
'Ready for relay',
|
||||
'Relayed',
|
||||
] as const;
|
||||
|
||||
export type OptimisticL2WithdrawalStatus = typeof WITHDRAWAL_STATUSES[number];
|
||||
|
||||
export type OptimisticL2WithdrawalsResponse = {
|
||||
items: Array<OptimisticL2WithdrawalsItem>;
|
||||
'next_page_params': {
|
||||
'items_count': number;
|
||||
'nonce': string;
|
||||
};
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import type { AddressParam } from './addressParams';
|
||||
import type { BlockTransactionsResponse } from './block';
|
||||
import type { DecodedInput } from './decodedInput';
|
||||
import type { Fee } from './fee';
|
||||
import type { L2WithdrawalStatus } from './l2Withdrawals';
|
||||
import type { OptimisticL2WithdrawalStatus } from './optimisticL2';
|
||||
import type { TokenInfo } from './token';
|
||||
import type { TokenTransfer } from './tokenTransfer';
|
||||
import type { TxAction } from './txAction';
|
||||
@@ -17,7 +17,7 @@ type WrappedTransactionFields = 'decoded_input' | 'fee' | 'gas_limit' | 'gas_pri
|
||||
export interface OpWithdrawal {
|
||||
l1_transaction_hash: string;
|
||||
nonce: number;
|
||||
status: L2WithdrawalStatus;
|
||||
status: OptimisticL2WithdrawalStatus;
|
||||
}
|
||||
|
||||
export type Transaction = {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { ArrayElement } from 'types/utils';
|
||||
|
||||
export const ROLLUP_TYPES = [
|
||||
'optimistic',
|
||||
'zkEvm',
|
||||
] as const;
|
||||
|
||||
export type RollupType = ArrayElement<typeof ROLLUP_TYPES>;
|
||||
@@ -9,8 +9,8 @@ import ActionBar from 'ui/shared/ActionBar';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import Pagination from 'ui/shared/pagination/Pagination';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import WithdrawalsListItem from 'ui/withdrawals/WithdrawalsListItem';
|
||||
import WithdrawalsTable from 'ui/withdrawals/WithdrawalsTable';
|
||||
import BeaconChainWithdrawalsListItem from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsListItem';
|
||||
import BeaconChainWithdrawalsTable from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable';
|
||||
|
||||
const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivElement>}) => {
|
||||
const router = useRouter();
|
||||
@@ -32,7 +32,7 @@ const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
{ data.items.map((item, index) => (
|
||||
<WithdrawalsListItem
|
||||
<BeaconChainWithdrawalsListItem
|
||||
key={ item.index + Number(isPlaceholderData ? index : '') }
|
||||
item={ item }
|
||||
view="address"
|
||||
@@ -41,7 +41,7 @@ const AddressWithdrawals = ({ scrollRef }: {scrollRef?: React.RefObject<HTMLDivE
|
||||
)) }
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<WithdrawalsTable items={ data.items } view="address" top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
<BeaconChainWithdrawalsTable items={ data.items } view="address" top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null ;
|
||||
|
||||
@@ -34,7 +34,7 @@ interface Props {
|
||||
query: BlockQuery;
|
||||
}
|
||||
|
||||
const isRollup = config.features.optimisticRollup.isEnabled || config.features.zkEvmRollup.isEnabled;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const BlockDetails = ({ query }: Props) => {
|
||||
const [ isExpanded, setIsExpanded ] = React.useState(false);
|
||||
@@ -73,7 +73,7 @@ const BlockDetails = ({ query }: Props) => {
|
||||
const validatorTitle = getNetworkValidatorTitle();
|
||||
|
||||
const rewardBreakDown = (() => {
|
||||
if (isRollup || totalReward.isEqualTo(ZERO) || txFees.isEqualTo(ZERO) || burntFees.isEqualTo(ZERO)) {
|
||||
if (rollupFeature.isEnabled || totalReward.isEqualTo(ZERO) || txFees.isEqualTo(ZERO) || burntFees.isEqualTo(ZERO)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ const BlockDetails = ({ query }: Props) => {
|
||||
})();
|
||||
|
||||
const verificationTitle = (() => {
|
||||
if (config.features.zkEvmRollup.isEnabled) {
|
||||
if (rollupFeature.isEnabled && rollupFeature.type === 'zkEvm') {
|
||||
return 'Sequenced by';
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ const BlockDetails = ({ query }: Props) => {
|
||||
{ /* <Text>{ dayjs.duration(block.minedIn, 'second').humanize(true) }</Text> */ }
|
||||
</DetailsInfoItem>
|
||||
) }
|
||||
{ !isRollup && !totalReward.isEqualTo(ZERO) && !config.UI.views.block.hiddenFields?.total_reward && (
|
||||
{ !rollupFeature.isEnabled && !totalReward.isEqualTo(ZERO) && !config.UI.views.block.hiddenFields?.total_reward && (
|
||||
<DetailsInfoItem
|
||||
title="Block reward"
|
||||
hint={
|
||||
|
||||
@@ -3,8 +3,8 @@ import React from 'react';
|
||||
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import type { QueryWithPagesResult } from 'ui/shared/pagination/useQueryWithPages';
|
||||
import WithdrawalsList from 'ui/withdrawals/WithdrawalsList';
|
||||
import WithdrawalsTable from 'ui/withdrawals/WithdrawalsTable';
|
||||
import BeaconChainWithdrawalsList from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsList';
|
||||
import BeaconChainWithdrawalsTable from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable';
|
||||
|
||||
type Props = {
|
||||
blockWithdrawalsQuery: QueryWithPagesResult<'block_withdrawals'>;
|
||||
@@ -14,14 +14,14 @@ const BlockWithdrawals = ({ blockWithdrawalsQuery }: Props) => {
|
||||
const content = blockWithdrawalsQuery.data?.items ? (
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
<WithdrawalsList
|
||||
<BeaconChainWithdrawalsList
|
||||
items={ blockWithdrawalsQuery.data.items }
|
||||
isLoading={ blockWithdrawalsQuery.isPlaceholderData }
|
||||
view="block"
|
||||
/>
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<WithdrawalsTable
|
||||
<BeaconChainWithdrawalsTable
|
||||
items={ blockWithdrawalsQuery.data.items }
|
||||
isLoading={ blockWithdrawalsQuery.isPlaceholderData }
|
||||
top={ blockWithdrawalsQuery.pagination.isVisible ? 80 : 0 }
|
||||
|
||||
@@ -28,7 +28,7 @@ interface Props {
|
||||
enableTimeIncrement?: boolean;
|
||||
}
|
||||
|
||||
const isRollup = config.features.optimisticRollup.isEnabled || config.features.zkEvmRollup.isEnabled;
|
||||
const isRollup = config.features.rollup.isEnabled;
|
||||
|
||||
const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
|
||||
const totalReward = getBlockTotalReward(data);
|
||||
|
||||
@@ -28,7 +28,7 @@ const GAS_COL_WEIGHT = 33;
|
||||
const REWARD_COL_WEIGHT = 22;
|
||||
const FEES_COL_WEIGHT = 22;
|
||||
|
||||
const isRollup = config.features.optimisticRollup.isEnabled || config.features.zkEvmRollup.isEnabled;
|
||||
const isRollup = config.features.rollup.isEnabled;
|
||||
|
||||
const BlocksTable = ({ data, isLoading, top, page, showSocketInfo, socketInfoNum, socketInfoAlert }: Props) => {
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ interface Props {
|
||||
enableTimeIncrement?: boolean;
|
||||
}
|
||||
|
||||
const isRollup = config.features.optimisticRollup.isEnabled || config.features.zkEvmRollup.isEnabled;
|
||||
const isRollup = config.features.rollup.isEnabled;
|
||||
|
||||
const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
|
||||
const totalReward = getBlockTotalReward(data);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Skeleton } from '@chakra-ui/react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
@@ -12,14 +12,14 @@ import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2DepositsItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean };
|
||||
|
||||
const DepositsListItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticDepositsListItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -80,4 +80,4 @@ const DepositsListItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DepositsListItem;
|
||||
export default OptimisticDepositsListItem;
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import { default as Thead } from 'ui/shared/TheadSticky';
|
||||
|
||||
import DepositsTableItem from './DepositsTableItem';
|
||||
import OptimisticDepositsTableItem from './OptimisticDepositsTableItem';
|
||||
|
||||
type Props = {
|
||||
items: Array<L2DepositsItem>;
|
||||
items: Array<OptimisticL2DepositsItem>;
|
||||
top: number;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const DepositsTable = ({ items, top, isLoading }: Props) => {
|
||||
const OptimisticDepositsTable = ({ items, top, isLoading }: Props) => {
|
||||
return (
|
||||
<Table variant="simple" size="sm" style={{ tableLayout: 'auto' }} minW="950px">
|
||||
<Thead top={ top }>
|
||||
@@ -28,11 +28,11 @@ const DepositsTable = ({ items, top, isLoading }: Props) => {
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{ items.map((item, index) => (
|
||||
<DepositsTableItem key={ item.l2_tx_hash + (isLoading ? index : '') } item={ item } isLoading={ isLoading }/>
|
||||
<OptimisticDepositsTableItem key={ item.l2_tx_hash + (isLoading ? index : '') } item={ item } isLoading={ isLoading }/>
|
||||
)) }
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
export default DepositsTable;
|
||||
export default OptimisticDepositsTable;
|
||||
@@ -2,7 +2,7 @@ import { Td, Tr, Skeleton } from '@chakra-ui/react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
@@ -11,14 +11,14 @@ import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2DepositsItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2DepositsItem; isLoading?: boolean };
|
||||
|
||||
const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticDepositsTableItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -71,4 +71,4 @@ const WithdrawalsTableItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default WithdrawalsTableItem;
|
||||
export default OptimisticDepositsTableItem;
|
||||
@@ -24,7 +24,7 @@ const LatestBlocks = () => {
|
||||
const isMobile = useIsMobile();
|
||||
// const blocksMaxCount = isMobile ? 2 : 3;
|
||||
let blocksMaxCount: number;
|
||||
if (config.features.optimisticRollup.isEnabled || config.UI.views.block.hiddenFields?.total_reward) {
|
||||
if (config.features.rollup.isEnabled || config.UI.views.block.hiddenFields?.total_reward) {
|
||||
blocksMaxCount = isMobile ? 4 : 5;
|
||||
} else {
|
||||
blocksMaxCount = isMobile ? 2 : 3;
|
||||
|
||||
@@ -59,14 +59,14 @@ const LatestBlocksItem = ({ block, isLoading }: Props) => {
|
||||
<Skeleton isLoaded={ !isLoading }>Txn</Skeleton>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary"><span>{ block.tx_count }</span></Skeleton>
|
||||
|
||||
{ !config.features.optimisticRollup.isEnabled && !config.UI.views.block.hiddenFields?.total_reward && (
|
||||
{ !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.total_reward && (
|
||||
<>
|
||||
<Skeleton isLoaded={ !isLoading }>Reward</Skeleton>
|
||||
<Skeleton isLoaded={ !isLoading } color="text_secondary"><span>{ totalReward.dp(10).toFixed() }</span></Skeleton>
|
||||
</>
|
||||
) }
|
||||
|
||||
{ !config.features.optimisticRollup.isEnabled && !config.UI.views.block.hiddenFields?.miner && (
|
||||
{ !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.miner && (
|
||||
<>
|
||||
<Skeleton isLoaded={ !isLoading } textTransform="capitalize">{ getNetworkValidatorTitle() }</Skeleton>
|
||||
<AddressEntity
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2DepositsItem } from 'types/api/l2Deposits';
|
||||
import type { OptimisticL2DepositsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
@@ -15,18 +15,18 @@ import BlockEntityL1 from 'ui/shared/entities/block/BlockEntityL1';
|
||||
import TxEntity from 'ui/shared/entities/tx/TxEntity';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const feature = config.features.rollup;
|
||||
|
||||
type Props = {
|
||||
item: L2DepositsItem;
|
||||
item: OptimisticL2DepositsItem;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const LatestTxsItem = ({ item, isLoading }: Props) => {
|
||||
const LatestDepositsItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_block_timestamp).fromNow();
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!feature.isEnabled || feature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -116,4 +116,4 @@ const LatestTxsItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(LatestTxsItem);
|
||||
export default React.memo(LatestDepositsItem);
|
||||
|
||||
@@ -13,7 +13,7 @@ const BATCHES_API_URL = buildApiUrl('homepage_zkevm_l2_batches');
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
context: contextWithEnvs(configs.featureEnvs.zkRollup) as any,
|
||||
context: contextWithEnvs(configs.featureEnvs.zkEvmRollup) as any,
|
||||
});
|
||||
|
||||
test('default view +@mobile +@dark-mode', async({ mount, page }) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AnimatePresence } from 'framer-motion';
|
||||
import React from 'react';
|
||||
|
||||
import type { SocketMessage } from 'lib/socket/types';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ import {
|
||||
import { motion } from 'framer-motion';
|
||||
import React from 'react';
|
||||
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import BlockTimestamp from 'ui/blocks/BlockTimestamp';
|
||||
import ZkEvmBatchEntityL2 from 'ui/shared/entities/block/ZkEvmBatchEntityL2';
|
||||
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
|
||||
import LinkInternal from 'ui/shared/LinkInternal';
|
||||
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
|
||||
|
||||
@@ -35,7 +35,7 @@ const LatestZkevmL2BatchItem = ({ batch, isLoading }: Props) => {
|
||||
p={ 6 }
|
||||
>
|
||||
<Flex alignItems="center" overflow="hidden" w="100%" mb={ 3 }>
|
||||
<ZkEvmBatchEntityL2
|
||||
<BatchEntityL2
|
||||
isLoading={ isLoading }
|
||||
number={ batch.number }
|
||||
tailLength={ 2 }
|
||||
|
||||
@@ -15,6 +15,7 @@ import StatsItem from './StatsItem';
|
||||
|
||||
const hasGasTracker = config.UI.homepage.showGasTracker;
|
||||
const hasAvgBlockTime = config.UI.homepage.showAvgBlockTime;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const Stats = () => {
|
||||
const { data, isPlaceholderData, isError, dataUpdatedAt } = useApiQuery('homepage_stats', {
|
||||
@@ -32,7 +33,7 @@ const Stats = () => {
|
||||
const zkEvmLatestBatchQuery = useApiQuery('homepage_zkevm_latest_batch', {
|
||||
queryOptions: {
|
||||
placeholderData: 12345,
|
||||
enabled: config.features.zkEvmRollup.isEnabled,
|
||||
enabled: rollupFeature.isEnabled && rollupFeature.type === 'zkEvm',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -68,7 +69,7 @@ const Stats = () => {
|
||||
|
||||
content = (
|
||||
<>
|
||||
{ config.features.zkEvmRollup.isEnabled ? (
|
||||
{ rollupFeature.isEnabled && rollupFeature.type === 'zkEvm' ? (
|
||||
<StatsItem
|
||||
icon="txn_batches"
|
||||
title="Latest batch"
|
||||
|
||||
@@ -7,13 +7,14 @@ import LatestDeposits from 'ui/home/LatestDeposits';
|
||||
import LatestTxs from 'ui/home/LatestTxs';
|
||||
import LatestWatchlistTxs from 'ui/home/LatestWatchlistTxs';
|
||||
import TabsWithScroll from 'ui/shared/Tabs/TabsWithScroll';
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const TransactionsHome = () => {
|
||||
const hasAccount = useHasAccount();
|
||||
if (config.features.optimisticRollup.isEnabled || hasAccount) {
|
||||
if ((rollupFeature.isEnabled && rollupFeature.type === 'optimistic') || hasAccount) {
|
||||
const tabs = [
|
||||
{ id: 'txn', title: 'Latest txn', component: <LatestTxs/> },
|
||||
config.features.optimisticRollup.isEnabled && { id: 'deposits', title: 'Deposits (L1→L2 txn)', component: <LatestDeposits/> },
|
||||
rollupFeature.isEnabled && rollupFeature.type === 'optimistic' && { id: 'deposits', title: 'Deposits (L1→L2 txn)', component: <LatestDeposits/> },
|
||||
hasAccount && { id: 'watchlist', title: 'Watch list', component: <LatestWatchlistTxs/> },
|
||||
].filter(Boolean);
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Flex, Skeleton } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2OutputRootsItem } from 'types/api/l2OutputRoots';
|
||||
import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
@@ -11,14 +11,14 @@ import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
|
||||
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2OutputRootsItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean };
|
||||
|
||||
const OutputRootsListItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticL2OutputRootsListItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -72,4 +72,4 @@ const OutputRootsListItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default OutputRootsListItem;
|
||||
export default OptimisticL2OutputRootsListItem;
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2OutputRootsItem } from 'types/api/l2OutputRoots';
|
||||
import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import { default as Thead } from 'ui/shared/TheadSticky';
|
||||
|
||||
import OutputRootsTableItem from './OutputRootsTableItem';
|
||||
import OptimisticL2OutputRootsTableItem from './OptimisticL2OutputRootsTableItem';
|
||||
|
||||
type Props = {
|
||||
items: Array<L2OutputRootsItem>;
|
||||
items: Array<OptimisticL2OutputRootsItem>;
|
||||
top: number;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const OutputRootsTable = ({ items, top, isLoading }: Props) => {
|
||||
const OptimisticL2OutputRootsTable = ({ items, top, isLoading }: Props) => {
|
||||
return (
|
||||
<Table variant="simple" size="sm" minW="900px">
|
||||
<Thead top={ top }>
|
||||
@@ -27,11 +27,15 @@ const OutputRootsTable = ({ items, top, isLoading }: Props) => {
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{ items.map((item, index) => (
|
||||
<OutputRootsTableItem key={ item.l2_output_index + (Number(isLoading ? index : '') ? String(index) : '') } item={ item } isLoading={ isLoading }/>
|
||||
<OptimisticL2OutputRootsTableItem
|
||||
key={ item.l2_output_index + (Number(isLoading ? index : '') ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isLoading }
|
||||
/>
|
||||
)) }
|
||||
</Tbody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
export default OutputRootsTable;
|
||||
export default OptimisticL2OutputRootsTable;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Flex, Td, Tr, Skeleton } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2OutputRootsItem } from 'types/api/l2OutputRoots';
|
||||
import type { OptimisticL2OutputRootsItem } from 'types/api/optimisticL2';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
@@ -10,14 +10,14 @@ import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2OutputRootsItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2OutputRootsItem; isLoading?: boolean };
|
||||
|
||||
const OutputRootsTableItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticL2OutputRootsTableItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -58,4 +58,4 @@ const OutputRootsTableItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default OutputRootsTableItem;
|
||||
export default OptimisticL2OutputRootsTableItem;
|
||||
@@ -7,7 +7,7 @@ import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import Withdrawals from './Withdrawals';
|
||||
import BeaconChainWithdrawals from './BeaconChainWithdrawals';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -35,7 +35,7 @@ test('base view +@mobile', async({ mount, page }) => {
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<Withdrawals/>
|
||||
<BeaconChainWithdrawals/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -12,8 +12,8 @@ import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
import WithdrawalsListItem from 'ui/withdrawals/WithdrawalsListItem';
|
||||
import WithdrawalsTable from 'ui/withdrawals/WithdrawalsTable';
|
||||
import BeaconChainWithdrawalsListItem from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsListItem';
|
||||
import BeaconChainWithdrawalsTable from 'ui/withdrawals/beaconChain/BeaconChainWithdrawalsTable';
|
||||
|
||||
const feature = config.features.beaconChain;
|
||||
|
||||
@@ -41,7 +41,7 @@ const Withdrawals = () => {
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
{ data.items.map(((item, index) => (
|
||||
<WithdrawalsListItem
|
||||
<BeaconChainWithdrawalsListItem
|
||||
key={ item.index + (isPlaceholderData ? String(index) : '') }
|
||||
item={ item }
|
||||
view="list"
|
||||
@@ -50,7 +50,7 @@ const Withdrawals = () => {
|
||||
))) }
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<WithdrawalsTable items={ data.items } view="list" top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
<BeaconChainWithdrawalsTable items={ data.items } view="list" top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null;
|
||||
@@ -12,6 +12,8 @@ import ProfileMenuDesktop from 'ui/snippets/profileMenu/ProfileMenuDesktop';
|
||||
import SearchBar from 'ui/snippets/searchBar/SearchBar';
|
||||
import WalletMenuDesktop from 'ui/snippets/walletMenu/WalletMenuDesktop';
|
||||
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const Home = () => {
|
||||
return (
|
||||
<Box as="main">
|
||||
@@ -44,7 +46,7 @@ const Home = () => {
|
||||
<ChainIndicators/>
|
||||
<AdBanner mt={{ base: 6, lg: 8 }} mx="auto" display="flex" justifyContent="center"/>
|
||||
<Flex mt={ 8 } direction={{ base: 'column', lg: 'row' }} columnGap={ 12 } rowGap={ 8 }>
|
||||
{ config.features.zkEvmRollup.isEnabled ? <LatestZkEvmL2Batches/> : <LatestBlocks/> }
|
||||
{ rollupFeature.isEnabled && rollupFeature.type === 'zkEvm' ? <LatestZkEvmL2Batches/> : <LatestBlocks/> }
|
||||
<Box flexGrow={ 1 }>
|
||||
<Transactions/>
|
||||
</Box>
|
||||
|
||||
@@ -7,7 +7,7 @@ import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import L2Deposits from './L2Deposits';
|
||||
import OptimisticL2Deposits from './OptimisticL2Deposits';
|
||||
|
||||
const DEPOSITS_API_URL = buildApiUrl('l2_deposits');
|
||||
const DEPOSITS_COUNT_API_URL = buildApiUrl('l2_deposits_count');
|
||||
@@ -40,7 +40,7 @@ test('base view +@mobile', async({ mount, page }) => {
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<L2Deposits/>
|
||||
<OptimisticL2Deposits/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -5,14 +5,14 @@ import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { rightLineArrow, nbsp } from 'lib/html-entities';
|
||||
import { L2_DEPOSIT_ITEM } from 'stubs/L2';
|
||||
import { generateListStub } from 'stubs/utils';
|
||||
import DepositsListItem from 'ui/l2Deposits/DepositsListItem';
|
||||
import DepositsTable from 'ui/l2Deposits/DepositsTable';
|
||||
import OptimisticDepositsListItem from 'ui/deposits/optimisticL2/OptimisticDepositsListItem';
|
||||
import OptimisticDepositsTable from 'ui/deposits/optimisticL2/OptimisticDepositsTable';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
|
||||
const L2Deposits = () => {
|
||||
const OptimisticL2Deposits = () => {
|
||||
const { data, isError, isPlaceholderData, pagination } = useQueryWithPages({
|
||||
resourceName: 'l2_deposits',
|
||||
options: {
|
||||
@@ -40,7 +40,7 @@ const L2Deposits = () => {
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
{ data.items.map(((item, index) => (
|
||||
<DepositsListItem
|
||||
<OptimisticDepositsListItem
|
||||
key={ item.l2_tx_hash + (isPlaceholderData ? index : '') }
|
||||
isLoading={ isPlaceholderData }
|
||||
item={ item }
|
||||
@@ -48,7 +48,7 @@ const L2Deposits = () => {
|
||||
))) }
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<DepositsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
<OptimisticDepositsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null;
|
||||
@@ -84,4 +84,4 @@ const L2Deposits = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default L2Deposits;
|
||||
export default OptimisticL2Deposits;
|
||||
@@ -7,7 +7,7 @@ import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import OutputRoots from './L2OutputRoots';
|
||||
import OptimisticL2OutputRoots from './OptimisticL2OutputRoots';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -40,7 +40,7 @@ test('base view +@mobile', async({ mount, page }) => {
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<OutputRoots/>
|
||||
<OptimisticL2OutputRoots/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -4,14 +4,14 @@ import React from 'react';
|
||||
import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { L2_OUTPUT_ROOTS_ITEM } from 'stubs/L2';
|
||||
import { generateListStub } from 'stubs/utils';
|
||||
import OutputRootsListItem from 'ui/l2OutputRoots/OutputRootsListItem';
|
||||
import OutputRootsTable from 'ui/l2OutputRoots/OutputRootsTable';
|
||||
import OptimisticL2OutputRootsListItem from 'ui/outputRoots/optimisticL2/OptimisticL2OutputRootsListItem';
|
||||
import OptimisticL2OutputRootsTable from 'ui/outputRoots/optimisticL2/OptimisticL2OutputRootsTable';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
|
||||
const L2OutputRoots = () => {
|
||||
const OptimisticL2OutputRoots = () => {
|
||||
const { data, isError, isPlaceholderData, pagination } = useQueryWithPages({
|
||||
resourceName: 'l2_output_roots',
|
||||
options: {
|
||||
@@ -38,7 +38,7 @@ const L2OutputRoots = () => {
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
{ data.items.map(((item, index) => (
|
||||
<OutputRootsListItem
|
||||
<OptimisticL2OutputRootsListItem
|
||||
key={ item.l2_output_index + (isPlaceholderData ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isPlaceholderData }
|
||||
@@ -46,7 +46,7 @@ const L2OutputRoots = () => {
|
||||
))) }
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<OutputRootsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
<OptimisticL2OutputRootsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null;
|
||||
@@ -82,4 +82,4 @@ const L2OutputRoots = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default L2OutputRoots;
|
||||
export default OptimisticL2OutputRoots;
|
||||
@@ -7,7 +7,7 @@ import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import L2TxnBatches from './L2TxnBatches';
|
||||
import OptimisticL2TxnBatches from './OptimisticL2TxnBatches';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -40,7 +40,7 @@ test('base view +@mobile', async({ mount, page }) => {
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<L2TxnBatches/>
|
||||
<OptimisticL2TxnBatches/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -5,14 +5,14 @@ import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { nbsp } from 'lib/html-entities';
|
||||
import { L2_TXN_BATCHES_ITEM } from 'stubs/L2';
|
||||
import { generateListStub } from 'stubs/utils';
|
||||
import TxnBatchesListItem from 'ui/l2TxnBatches/TxnBatchesListItem';
|
||||
import TxnBatchesTable from 'ui/l2TxnBatches/TxnBatchesTable';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
import OptimisticL2TxnBatchesListItem from 'ui/txnBatches/optimisticL2/OptimisticL2TxnBatchesListItem';
|
||||
import OptimisticL2TxnBatchesTable from 'ui/txnBatches/optimisticL2/OptimisticL2TxnBatchesTable';
|
||||
|
||||
const L2TxnBatches = () => {
|
||||
const OptimisticL2TxnBatches = () => {
|
||||
const { data, isError, isPlaceholderData, pagination } = useQueryWithPages({
|
||||
resourceName: 'l2_txn_batches',
|
||||
options: {
|
||||
@@ -39,14 +39,16 @@ const L2TxnBatches = () => {
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>
|
||||
{ data.items.map(((item, index) => (
|
||||
<TxnBatchesListItem
|
||||
<OptimisticL2TxnBatchesListItem
|
||||
key={ item.l2_block_number + (isPlaceholderData ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isPlaceholderData }
|
||||
/>
|
||||
))) }
|
||||
</Show>
|
||||
<Hide below="lg" ssr={ false }><TxnBatchesTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/></Hide>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<OptimisticL2TxnBatchesTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null;
|
||||
|
||||
@@ -81,4 +83,4 @@ const L2TxnBatches = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default L2TxnBatches;
|
||||
export default OptimisticL2TxnBatches;
|
||||
@@ -7,7 +7,7 @@ import TestApp from 'playwright/TestApp';
|
||||
import buildApiUrl from 'playwright/utils/buildApiUrl';
|
||||
import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import L2Withdrawals from './L2Withdrawals';
|
||||
import OptimisticL2Withdrawals from './OptimisticL2Withdrawals';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -40,7 +40,7 @@ test('base view +@mobile', async({ mount, page }) => {
|
||||
|
||||
const component = await mount(
|
||||
<TestApp>
|
||||
<L2Withdrawals/>
|
||||
<OptimisticL2Withdrawals/>
|
||||
</TestApp>,
|
||||
);
|
||||
|
||||
@@ -5,14 +5,14 @@ import useApiQuery from 'lib/api/useApiQuery';
|
||||
import { rightLineArrow, nbsp } from 'lib/html-entities';
|
||||
import { L2_WITHDRAWAL_ITEM } from 'stubs/L2';
|
||||
import { generateListStub } from 'stubs/utils';
|
||||
import WithdrawalsListItem from 'ui/l2Withdrawals/WithdrawalsListItem';
|
||||
import WithdrawalsTable from 'ui/l2Withdrawals/WithdrawalsTable';
|
||||
import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
import OptimisticL2WithdrawalsListItem from 'ui/withdrawals/optimisticL2/OptimisticL2WithdrawalsListItem';
|
||||
import OptimisticL2WithdrawalsTable from 'ui/withdrawals/optimisticL2/OptimisticL2WithdrawalsTable';
|
||||
|
||||
const L2Withdrawals = () => {
|
||||
const OptimisticL2Withdrawals = () => {
|
||||
const { data, isError, isPlaceholderData, pagination } = useQueryWithPages({
|
||||
resourceName: 'l2_withdrawals',
|
||||
options: {
|
||||
@@ -38,14 +38,14 @@ const L2Withdrawals = () => {
|
||||
const content = data?.items ? (
|
||||
<>
|
||||
<Show below="lg" ssr={ false }>{ data.items.map(((item, index) => (
|
||||
<WithdrawalsListItem
|
||||
<OptimisticL2WithdrawalsListItem
|
||||
key={ item.l2_tx_hash + (isPlaceholderData ? index : '') }
|
||||
item={ item }
|
||||
isLoading={ isPlaceholderData }
|
||||
/>
|
||||
))) }</Show>
|
||||
<Hide below="lg" ssr={ false }>
|
||||
<WithdrawalsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
<OptimisticL2WithdrawalsTable items={ data.items } top={ pagination.isVisible ? 80 : 0 } isLoading={ isPlaceholderData }/>
|
||||
</Hide>
|
||||
</>
|
||||
) : null;
|
||||
@@ -81,4 +81,4 @@ const L2Withdrawals = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default L2Withdrawals;
|
||||
export default OptimisticL2Withdrawals;
|
||||
@@ -11,7 +11,7 @@ import ZkEvmL2TxnBatch from './ZkEvmL2TxnBatch';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
context: contextWithEnvs(configs.featureEnvs.zkRollup) as any,
|
||||
context: contextWithEnvs(configs.featureEnvs.zkEvmRollup) as any,
|
||||
});
|
||||
|
||||
const hooksConfig = {
|
||||
|
||||
@@ -16,8 +16,8 @@ import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import RoutedTabs from 'ui/shared/Tabs/RoutedTabs';
|
||||
import TabsSkeleton from 'ui/shared/Tabs/TabsSkeleton';
|
||||
import ZkEvmL2TxnBatchDetails from 'ui/txnBatches/zkEvmL2/ZkEvmL2TxnBatchDetails';
|
||||
import TxsWithFrontendSorting from 'ui/txs/TxsWithFrontendSorting';
|
||||
import ZkEvmL2TxnBatchDetails from 'ui/zkEvmL2TxnBatches/ZkEvmL2TxnBatchDetails';
|
||||
|
||||
const ZkEvmL2TxnBatch = () => {
|
||||
const router = useRouter();
|
||||
|
||||
@@ -11,7 +11,7 @@ import ZkEvmL2TxnBatches from './ZkEvmL2TxnBatches';
|
||||
|
||||
const test = base.extend({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
context: contextWithEnvs(configs.featureEnvs.zkRollup) as any,
|
||||
context: contextWithEnvs(configs.featureEnvs.zkEvmRollup) as any,
|
||||
});
|
||||
|
||||
const BATCHES_API_URL = buildApiUrl('zkevm_l2_txn_batches');
|
||||
|
||||
@@ -8,8 +8,8 @@ import DataListDisplay from 'ui/shared/DataListDisplay';
|
||||
import PageTitle from 'ui/shared/Page/PageTitle';
|
||||
import useQueryWithPages from 'ui/shared/pagination/useQueryWithPages';
|
||||
import StickyPaginationWithText from 'ui/shared/StickyPaginationWithText';
|
||||
import ZkEvmTxnBatchesListItem from 'ui/zkEvmL2TxnBatches/ZkEvmTxnBatchesListItem';
|
||||
import ZkEvmTxnBatchesTable from 'ui/zkEvmL2TxnBatches/ZkEvmTxnBatchesTable';
|
||||
import ZkEvmTxnBatchesListItem from 'ui/txnBatches/zkEvmL2/ZkEvmTxnBatchesListItem';
|
||||
import ZkEvmTxnBatchesTable from 'ui/txnBatches/zkEvmL2/ZkEvmTxnBatchesTable';
|
||||
|
||||
const ZkEvmL2TxnBatches = () => {
|
||||
const { data, isError, isPlaceholderData, pagination } = useQueryWithPages({
|
||||
|
||||
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
@@ -7,14 +7,14 @@ import config from 'configs/app';
|
||||
|
||||
import * as AddressEntity from './AddressEntity';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const AddressEntityL1 = (props: AddressEntity.EntityProps) => {
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const defaultHref = feature.L1BaseUrl + route({
|
||||
const defaultHref = rollupFeature.L1BaseUrl + route({
|
||||
pathname: '/address/[hash]',
|
||||
query: {
|
||||
...props.query,
|
||||
|
||||
@@ -8,13 +8,13 @@ import config from 'configs/app';
|
||||
|
||||
import * as BlockEntity from './BlockEntity';
|
||||
|
||||
const feature = config.features.zkEvmRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const ZkEvmBatchEntityL2 = (props: BlockEntity.EntityProps) => {
|
||||
const BatchEntityL2 = (props: BlockEntity.EntityProps) => {
|
||||
const linkProps = _omit(props, [ 'className' ]);
|
||||
const partsProps = _omit(props, [ 'className', 'onClick' ]);
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ const ZkEvmBatchEntityL2 = (props: BlockEntity.EntityProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default chakra(ZkEvmBatchEntityL2);
|
||||
export default chakra(BatchEntityL2);
|
||||
@@ -8,13 +8,13 @@ import config from 'configs/app';
|
||||
|
||||
import * as BlockEntity from './BlockEntity';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const BlockEntityL1 = (props: BlockEntity.EntityProps) => {
|
||||
const linkProps = _omit(props, [ 'className' ]);
|
||||
const partsProps = _omit(props, [ 'className', 'onClick' ]);
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const BlockEntityL1 = (props: BlockEntity.EntityProps) => {
|
||||
<BlockEntity.Link
|
||||
{ ...linkProps }
|
||||
isExternal
|
||||
href={ feature.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: props.hash ?? String(props.number) } }) }
|
||||
href={ rollupFeature.L1BaseUrl + route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: props.hash ?? String(props.number) } }) }
|
||||
>
|
||||
<BlockEntity.Content { ...partsProps }/>
|
||||
</BlockEntity.Link>
|
||||
|
||||
@@ -6,13 +6,13 @@ import config from 'configs/app';
|
||||
|
||||
import * as BlockEntity from './BlockEntity';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const BlockEntityL2 = (props: BlockEntity.EntityProps) => {
|
||||
const linkProps = _omit(props, [ 'className' ]);
|
||||
const partsProps = _omit(props, [ 'className', 'onClick' ]);
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import config from 'configs/app';
|
||||
|
||||
import * as TxEntity from './TxEntity';
|
||||
|
||||
const feature = config.features.optimisticRollup.isEnabled ? config.features.optimisticRollup : config.features.zkEvmRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
const TxEntityL1 = (props: TxEntity.EntityProps) => {
|
||||
const partsProps = _omit(props, [ 'className', 'onClick' ]);
|
||||
const linkProps = _omit(props, [ 'className' ]);
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ const TxEntityL1 = (props: TxEntity.EntityProps) => {
|
||||
<TxEntity.Link
|
||||
{ ...linkProps }
|
||||
isExternal
|
||||
href={ feature.L1BaseUrl + route({ pathname: '/tx/[hash]', query: { hash: props.hash } }) }
|
||||
href={ rollupFeature.L1BaseUrl + route({ pathname: '/tx/[hash]', query: { hash: props.hash } }) }
|
||||
>
|
||||
<TxEntity.Content { ...partsProps }/>
|
||||
</TxEntity.Link>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import type { StatusTagType } from './StatusTag';
|
||||
import StatusTag from './StatusTag';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Box } from '@chakra-ui/react';
|
||||
import { test as base, expect } from '@playwright/experimental-ct-react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2WithdrawalStatus } from 'types/api/l2Withdrawals';
|
||||
import type { OptimisticL2WithdrawalStatus } from 'types/api/optimisticL2';
|
||||
|
||||
import contextWithEnvs from 'playwright/fixtures/contextWithEnvs';
|
||||
import TestApp from 'playwright/TestApp';
|
||||
@@ -10,7 +10,7 @@ import * as configs from 'playwright/utils/configs';
|
||||
|
||||
import TxDetailsWithdrawalStatus from './TxDetailsWithdrawalStatus';
|
||||
|
||||
const statuses: Array<L2WithdrawalStatus> = [
|
||||
const statuses: Array<OptimisticL2WithdrawalStatus> = [
|
||||
'Waiting for state root',
|
||||
'Ready for relay',
|
||||
'Relayed',
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Button } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2WithdrawalStatus } from 'types/api/l2Withdrawals';
|
||||
import { WITHDRAWAL_STATUSES } from 'types/api/l2Withdrawals';
|
||||
import type { OptimisticL2WithdrawalStatus } from 'types/api/optimisticL2';
|
||||
import { WITHDRAWAL_STATUSES } from 'types/api/optimisticL2';
|
||||
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import VerificationSteps from 'ui/shared/verificationSteps/VerificationSteps';
|
||||
|
||||
interface Props {
|
||||
status: L2WithdrawalStatus | undefined;
|
||||
status: OptimisticL2WithdrawalStatus | undefined;
|
||||
l1TxHash: string | undefined;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ const TxDetailsWithdrawalStatus = ({ status, l1TxHash }: Props) => {
|
||||
|
||||
return (
|
||||
<VerificationSteps
|
||||
steps={ steps as unknown as Array<L2WithdrawalStatus> }
|
||||
steps={ steps as unknown as Array<OptimisticL2WithdrawalStatus> }
|
||||
currentStep={ status }
|
||||
rightSlot={ rightSlot }
|
||||
my={ hasClaimButton ? '-6px' : 0 }
|
||||
|
||||
@@ -33,8 +33,8 @@ import DetailsInfoItemDivider from 'ui/shared/DetailsInfoItemDivider';
|
||||
import DetailsSponsoredItem from 'ui/shared/DetailsSponsoredItem';
|
||||
import DetailsTimestamp from 'ui/shared/DetailsTimestamp';
|
||||
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
|
||||
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
|
||||
import BlockEntity from 'ui/shared/entities/block/BlockEntity';
|
||||
import ZkEvmBatchEntityL2 from 'ui/shared/entities/block/ZkEvmBatchEntityL2';
|
||||
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
|
||||
import IconSvg from 'ui/shared/IconSvg';
|
||||
import LogDecodedInputData from 'ui/shared/logs/LogDecodedInputData';
|
||||
@@ -53,6 +53,9 @@ import TxDetailsWithdrawalStatus from 'ui/tx/details/TxDetailsWithdrawalStatus';
|
||||
import TxRevertReason from 'ui/tx/details/TxRevertReason';
|
||||
import TxAllowedPeekers from 'ui/tx/TxAllowedPeekers';
|
||||
import TxSocketAlert from 'ui/tx/TxSocketAlert';
|
||||
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
interface Props {
|
||||
data: Transaction | undefined;
|
||||
isLoading: boolean;
|
||||
@@ -123,7 +126,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
|
||||
<CopyToClipboard text={ data.hash } isLoading={ isLoading }/>
|
||||
</DetailsInfoItem>
|
||||
<DetailsInfoItem
|
||||
title={ config.features.zkEvmRollup.isEnabled ? 'L2 status and method' : 'Status and method' }
|
||||
title={ rollupFeature.isEnabled && rollupFeature.type === 'zkEvm' ? 'L2 status and method' : 'Status and method' }
|
||||
hint="Current transaction state: Success, Failed (Error), or Pending (In Process)"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
@@ -134,7 +137,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
|
||||
</Tag>
|
||||
) }
|
||||
</DetailsInfoItem>
|
||||
{ config.features.optimisticRollup.isEnabled && data.op_withdrawals && data.op_withdrawals.length > 0 && (
|
||||
{ rollupFeature.isEnabled && rollupFeature.type === 'optimistic' && data.op_withdrawals && data.op_withdrawals.length > 0 && (
|
||||
<DetailsInfoItem
|
||||
title="Withdrawal status"
|
||||
hint="Detailed status progress of the transaction"
|
||||
@@ -200,7 +203,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
|
||||
hint="Batch index for this transaction"
|
||||
isLoading={ isLoading }
|
||||
>
|
||||
<ZkEvmBatchEntityL2
|
||||
<BatchEntityL2
|
||||
isLoading={ isLoading }
|
||||
number={ data.zkevm_batch_number }
|
||||
/>
|
||||
@@ -419,7 +422,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
|
||||
) }
|
||||
</DetailsInfoItem>
|
||||
) }
|
||||
{ data.tx_burnt_fee && !config.UI.views.tx.hiddenFields?.burnt_fees && !config.features.optimisticRollup.isEnabled && (
|
||||
{ data.tx_burnt_fee && !config.UI.views.tx.hiddenFields?.burnt_fees && !(rollupFeature.isEnabled && rollupFeature.type === 'optimistic') && (
|
||||
<DetailsInfoItem
|
||||
title="Burnt fees"
|
||||
hint={ `Amount of ${ currencyUnits.ether } burned for this transaction. Equals Block Base Fee per Gas * Gas Used` }
|
||||
@@ -434,7 +437,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => {
|
||||
/>
|
||||
</DetailsInfoItem>
|
||||
) }
|
||||
{ config.features.optimisticRollup.isEnabled && (
|
||||
{ rollupFeature.isEnabled && rollupFeature.type === 'optimistic' && (
|
||||
<>
|
||||
{ data.l1_gas_used && (
|
||||
<DetailsInfoItem
|
||||
|
||||
@@ -18,6 +18,8 @@ import useSocketChannel from 'lib/socket/useSocketChannel';
|
||||
import useSocketMessage from 'lib/socket/useSocketMessage';
|
||||
import { TX, TX_ZKEVM_L2 } from 'stubs/tx';
|
||||
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
export type TxQuery = UseQueryResult<Transaction, ResourceError<{ status: number }>> & {
|
||||
socketStatus: 'close' | 'error' | undefined;
|
||||
setRefetchOnError: {
|
||||
@@ -46,7 +48,7 @@ export default function useTxQuery(params?: Params): TxQuery {
|
||||
queryOptions: {
|
||||
enabled: Boolean(hash) && params?.isEnabled !== false,
|
||||
refetchOnMount: false,
|
||||
placeholderData: config.features.zkEvmRollup.isEnabled ? TX_ZKEVM_L2 : TX,
|
||||
placeholderData: rollupFeature.isEnabled && rollupFeature.type === 'zkEvm' ? TX_ZKEVM_L2 : TX,
|
||||
retry: (failureCount, error) => {
|
||||
if (isRefetchEnabled) {
|
||||
return false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Skeleton, VStack } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2TxnBatchesItem } from 'types/api/l2TxnBatches';
|
||||
import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
@@ -13,14 +13,14 @@ import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import LinkInternal from 'ui/shared/LinkInternal';
|
||||
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2TxnBatchesItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean };
|
||||
|
||||
const TxnBatchesListItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticL2TxnBatchesListItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -87,4 +87,4 @@ const TxnBatchesListItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TxnBatchesListItem;
|
||||
export default OptimisticL2TxnBatchesListItem;
|
||||
@@ -1,19 +1,19 @@
|
||||
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2TxnBatchesItem } from 'types/api/l2TxnBatches';
|
||||
import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2';
|
||||
|
||||
import { default as Thead } from 'ui/shared/TheadSticky';
|
||||
|
||||
import TxnBatchesTableItem from './TxnBatchesTableItem';
|
||||
import OptimisticL2TxnBatchesTableItem from './OptimisticL2TxnBatchesTableItem';
|
||||
|
||||
type Props = {
|
||||
items: Array<L2TxnBatchesItem>;
|
||||
items: Array<OptimisticL2TxnBatchesItem>;
|
||||
top: number;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const TxnBatchesTable = ({ items, top, isLoading }: Props) => {
|
||||
const OptimisticL2TxnBatchesTable = ({ items, top, isLoading }: Props) => {
|
||||
return (
|
||||
<Table variant="simple" size="sm" minW="850px">
|
||||
<Thead top={ top }>
|
||||
@@ -27,7 +27,7 @@ const TxnBatchesTable = ({ items, top, isLoading }: Props) => {
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{ items.map((item, index) => (
|
||||
<TxnBatchesTableItem
|
||||
<OptimisticL2TxnBatchesTableItem
|
||||
key={ item.l2_block_number + (isLoading ? String(index) : '') }
|
||||
item={ item }
|
||||
isLoading={ isLoading }
|
||||
@@ -38,4 +38,4 @@ const TxnBatchesTable = ({ items, top, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TxnBatchesTable;
|
||||
export default OptimisticL2TxnBatchesTable;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Td, Tr, VStack, Skeleton } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { L2TxnBatchesItem } from 'types/api/l2TxnBatches';
|
||||
import type { OptimisticL2TxnBatchesItem } from 'types/api/optimisticL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
@@ -12,14 +12,14 @@ import BlockEntityL2 from 'ui/shared/entities/block/BlockEntityL2';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import LinkInternal from 'ui/shared/LinkInternal';
|
||||
|
||||
const feature = config.features.optimisticRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: L2TxnBatchesItem; isLoading?: boolean };
|
||||
type Props = { item: OptimisticL2TxnBatchesItem; isLoading?: boolean };
|
||||
|
||||
const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
|
||||
const OptimisticL2TxnBatchesTableItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.l1_timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'optimistic') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -78,4 +78,4 @@ const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TxnBatchesTableItem;
|
||||
export default OptimisticL2TxnBatchesTableItem;
|
||||
@@ -3,8 +3,8 @@ import type { UseQueryResult } from '@tanstack/react-query';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
|
||||
import { ZKEVM_L2_TX_BATCH_STATUSES } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatch } from 'types/api/zkEvmL2TxnBatches';
|
||||
import { ZKEVM_L2_TX_BATCH_STATUSES } from 'types/api/zkEvmL2';
|
||||
import type { ZkEvmL2TxnBatch } from 'types/api/zkEvmL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import { Skeleton, Text } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
import ZkEvmBatchEntityL2 from 'ui/shared/entities/block/ZkEvmBatchEntityL2';
|
||||
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import LinkInternal from 'ui/shared/LinkInternal';
|
||||
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
|
||||
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
|
||||
|
||||
const feature = config.features.zkEvmRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean };
|
||||
|
||||
const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const ZkEvmTxnBatchesListItem = ({ item, isLoading }: Props) => {
|
||||
|
||||
<ListItemMobileGrid.Label isLoading={ isLoading }>Batch #</ListItemMobileGrid.Label>
|
||||
<ListItemMobileGrid.Value>
|
||||
<ZkEvmBatchEntityL2
|
||||
<BatchEntityL2
|
||||
isLoading={ isLoading }
|
||||
number={ item.number }
|
||||
fontSize="sm"
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Table, Tbody, Th, Tr } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { default as Thead } from 'ui/shared/TheadSticky';
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import { Td, Tr, Text, Skeleton } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2TxnBatches';
|
||||
import type { ZkEvmL2TxnBatchesItem } from 'types/api/zkEvmL2';
|
||||
|
||||
import { route } from 'nextjs-routes';
|
||||
|
||||
import config from 'configs/app';
|
||||
import dayjs from 'lib/date/dayjs';
|
||||
import ZkEvmBatchEntityL2 from 'ui/shared/entities/block/ZkEvmBatchEntityL2';
|
||||
import BatchEntityL2 from 'ui/shared/entities/block/BatchEntityL2';
|
||||
import TxEntityL1 from 'ui/shared/entities/tx/TxEntityL1';
|
||||
import LinkInternal from 'ui/shared/LinkInternal';
|
||||
import ZkEvmL2TxnBatchStatus from 'ui/shared/statusTag/ZkEvmL2TxnBatchStatus';
|
||||
|
||||
const feature = config.features.zkEvmRollup;
|
||||
const rollupFeature = config.features.rollup;
|
||||
|
||||
type Props = { item: ZkEvmL2TxnBatchesItem; isLoading?: boolean };
|
||||
|
||||
const TxnBatchesTableItem = ({ item, isLoading }: Props) => {
|
||||
const timeAgo = dayjs(item.timestamp).fromNow();
|
||||
|
||||
if (!feature.isEnabled) {
|
||||
if (!rollupFeature.isEnabled || rollupFeature.type !== 'zkEvm') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tr>
|
||||
<Td verticalAlign="middle">
|
||||
<ZkEvmBatchEntityL2
|
||||
<BatchEntityL2
|
||||
isLoading={ isLoading }
|
||||
number={ item.number }
|
||||
fontSize="sm"
|
||||
@@ -7,7 +7,7 @@ import type { WithdrawalsItem } from 'types/api/withdrawals';
|
||||
|
||||
import useLazyRenderedList from 'lib/hooks/useLazyRenderedList';
|
||||
|
||||
import WithdrawalsListItem from './WithdrawalsListItem';
|
||||
import BeaconChainWithdrawalsListItem from './BeaconChainWithdrawalsListItem';
|
||||
|
||||
type Props = {
|
||||
isLoading?: boolean;
|
||||
@@ -34,7 +34,7 @@ const WithdrawalsList = ({ items, view, isLoading }: Props) => {
|
||||
switch (view) {
|
||||
case 'address': {
|
||||
return (
|
||||
<WithdrawalsListItem
|
||||
<BeaconChainWithdrawalsListItem
|
||||
key={ key }
|
||||
item={ item as AddressWithdrawalsItem }
|
||||
view={ view }
|
||||
@@ -44,7 +44,7 @@ const WithdrawalsList = ({ items, view, isLoading }: Props) => {
|
||||
}
|
||||
case 'block': {
|
||||
return (
|
||||
<WithdrawalsListItem
|
||||
<BeaconChainWithdrawalsListItem
|
||||
key={ key }
|
||||
item={ item as BlockWithdrawalsItem }
|
||||
view={ view }
|
||||
@@ -54,7 +54,7 @@ const WithdrawalsList = ({ items, view, isLoading }: Props) => {
|
||||
}
|
||||
case 'list': {
|
||||
return (
|
||||
<WithdrawalsListItem
|
||||
<BeaconChainWithdrawalsListItem
|
||||
key={ key }
|
||||
item={ item as WithdrawalsItem }
|
||||
view={ view }
|
||||
@@ -26,7 +26,7 @@ type Props = ({
|
||||
view: 'block';
|
||||
}) & { isLoading?: boolean };
|
||||
|
||||
const WithdrawalsListItem = ({ item, isLoading, view }: Props) => {
|
||||
const BeaconChainWithdrawalsListItem = ({ item, isLoading, view }: Props) => {
|
||||
if (!feature.isEnabled) {
|
||||
return null;
|
||||
}
|
||||
@@ -87,4 +87,4 @@ const WithdrawalsListItem = ({ item, isLoading, view }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default WithdrawalsListItem;
|
||||
export default BeaconChainWithdrawalsListItem;
|
||||